<!DOCTYPE html><html class=split lang=en-US-x-hixie><script src=../link-fixup.js defer=""></script>
<!-- Mirrored from html.spec.whatwg.org/multipage/custom-elements.html by HTTrack Website Copier/3.x [XR&CO'2014], Wed, 10 Sep 2025 08:35:51 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=utf-8" /><!-- /Added by HTTrack -->
<meta charset=utf-8><meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name=viewport><title>HTML Standard</title><meta content=#3c790a name=theme-color><meta content="light dark" name=color-scheme><link rel=stylesheet href=../../resources.whatwg.org/standard-shared-with-dev.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/standard.css crossorigin=""><link rel=stylesheet href=../../resources.whatwg.org/spec.css crossorigin=""><link rel=icon href=https://resources.whatwg.org/logo.svg crossorigin=""><link rel=stylesheet href=../styles.css crossorigin=""><script>
   function toggleStatus(div) {
     div.parentNode.classList.toggle('wrapped');
   }
   function setLinkFragment(link) {
     link.hash = location.hash;
   }
  </script><body>
  
  <script defer="" crossorigin="" src=../html-dfn.js></script>
  
  <header id=head class="head with-buttons">
   <a href=https://whatwg.org/ class=logo><img width=100 alt=WHATWG crossorigin="" class=darkmode-aware src=https://resources.whatwg.org/logo.svg height=100></a>
   <hgroup><h1 class=allcaps>HTML</h1><p id=living-standard>Living Standard — Last Updated <span class=pubdate>10 September 2025</span></hgroup>
   
   

   
  </header>

  

  

  

  
  

  
  

  

  <nav><a href=canvas.html>← 4.12.5 The canvas element</a> — <a href=index.html>Table of Contents</a> — <a href=semantics-other.html>4.14 Common idioms without dedicated elements →</a></nav><ol class=toc><li id=toc-semantics><ol><li><a href=custom-elements.html#custom-elements><span class=secno>4.13</span> Custom elements</a><ol><li><a href=custom-elements.html#custom-elements-intro><span class=secno>4.13.1</span> Introduction</a><ol><li><a href=custom-elements.html#custom-elements-autonomous-example><span class=secno>4.13.1.1</span> Creating an autonomous custom element</a><li><a href=custom-elements.html#custom-elements-face-example><span class=secno>4.13.1.2</span> Creating a form-associated custom element</a><li><a href=custom-elements.html#custom-elements-accessibility-example><span class=secno>4.13.1.3</span> Creating a custom element with default accessible roles, states, and properties</a><li><a href=custom-elements.html#custom-elements-customized-builtin-example><span class=secno>4.13.1.4</span> Creating a customized built-in element</a><li><a href=custom-elements.html#custom-elements-autonomous-drawbacks><span class=secno>4.13.1.5</span> Drawbacks of autonomous custom elements</a><li><a href=custom-elements.html#custom-elements-upgrades-examples><span class=secno>4.13.1.6</span> Upgrading elements after their creation</a><li><a href=custom-elements.html#scoped-custom-element-registries><span class=secno>4.13.1.7</span> Scoped custom element registries</a><li><a href=custom-elements.html#exposing-custom-element-states><span class=secno>4.13.1.8</span> Exposing custom element states</a></ol><li><a href=custom-elements.html#custom-element-conformance><span class=secno>4.13.2</span> Requirements for custom element constructors and
  reactions</a><ol><li><a href=custom-elements.html#preserving-custom-element-state-when-moved><span class=secno>4.13.2.1</span> Preserving custom element state when moved</a></ol><li><a href=custom-elements.html#custom-elements-core-concepts><span class=secno>4.13.3</span> Core concepts</a><li><a href=custom-elements.html#custom-elements-api><span class=secno>4.13.4</span> The <code>CustomElementRegistry</code> interface</a><li><a href=custom-elements.html#upgrades><span class=secno>4.13.5</span> Upgrades</a><li><a href=custom-elements.html#custom-element-reactions><span class=secno>4.13.6</span> Custom element reactions</a><li><a href=custom-elements.html#element-internals><span class=secno>4.13.7</span> Element internals</a><ol><li><a href=custom-elements.html#the-elementinternals-interface><span class=secno>4.13.7.1</span> The <code>ElementInternals</code> interface</a><li><a href=custom-elements.html#shadow-root-access><span class=secno>4.13.7.2</span> Shadow root access</a><li><a href=custom-elements.html#form-associated-custom-elements><span class=secno>4.13.7.3</span> Form-associated custom elements</a><li><a href=custom-elements.html#accessibility-semantics><span class=secno>4.13.7.4</span> Accessibility semantics</a><li><a href=custom-elements.html#custom-state-pseudo-class><span class=secno>4.13.7.5</span> Custom state pseudo-class</a></ol></ol></ol></ol><h3 id=custom-elements><span class=secno>4.13</span> Custom elements<a href=#custom-elements class=self-link></a></h3><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements title="One of the key features of the Web Components standard is the ability to create custom elements that encapsulate your functionality on an HTML page, rather than having to make do with a long, nested batch of elements that together provide a custom page feature. This article introduces the use of the Custom Elements API.">Using_custom_elements</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>63+</span></span><span class="safari yes"><span>Safari</span><span>10.1+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  <h4 id=custom-elements-intro><span class=secno>4.13.1</span> Introduction<a href=#custom-elements-intro class=self-link></a></h4>

  <p><i>This section is non-normative.</i></p>

  <p><a href=#custom-element id=custom-elements-intro:custom-element>Custom elements</a> provide a way for authors to build their
  own fully-featured DOM elements. Although authors could always use non-standard elements in their
  documents, with application-specific behavior added after the fact by scripting or similar, such
  elements have historically been non-conforming and not very functional. By <a href=#element-definition id=custom-elements-intro:element-definition>defining</a> a custom element, authors can inform the parser how to
  properly construct an element and how elements of that class should react to changes.</p>

  <p>Custom elements are part of a larger effort to "rationalise the platform", by explaining
  existing platform features (like the elements of HTML) in terms of lower-level author-exposed
  extensibility points (like custom element definition). Although today there are many limitations
  on the capabilities of custom elements—both functionally and semantically—that prevent them from
  fully explaining the behaviors of HTML's existing elements, we hope to shrink this gap over
  time.</p>

  <h5 id=custom-elements-autonomous-example><span class=secno>4.13.1.1</span> Creating an autonomous custom element<a href=#custom-elements-autonomous-example class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>For the purposes of illustrating how to create an <a href=#autonomous-custom-element id=custom-elements-autonomous-example:autonomous-custom-element>autonomous custom element</a>, let's
  define a custom element that encapsulates rendering a small icon for a country flag. Our goal is
  to be able to use it like so:</p>

  <pre><code class='html'><c- p>&lt;</c-><c- f>flag-icon</c-> <c- e>country</c-><c- o>=</c-><c- s>&quot;nl&quot;</c-><c- p>&gt;&lt;/</c-><c- f>flag-icon</c-><c- p>&gt;</c-></code></pre>

  <p>To do this, we first declare a class for the custom element, extending
  <code id=custom-elements-autonomous-example:htmlelement><a href=dom.html#htmlelement>HTMLElement</a></code>:</p>

  <pre><code class='js'><c- a>class</c-> FlagIcon <c- k>extends</c-> HTMLElement <c- p>{</c->
  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->
    <c- k>this</c-><c- p>.</c->_countryCode <c- o>=</c-> <c- kc>null</c-><c- p>;</c->
  <c- p>}</c->

  <c- k>static</c-> observedAttributes <c- o>=</c-> <c- p>[</c-><c- u>&quot;country&quot;</c-><c- p>];</c->

  attributeChangedCallback<c- p>(</c->name<c- p>,</c-> oldValue<c- p>,</c-> newValue<c- p>)</c-> <c- p>{</c->
    <c- c1>// name will always be &quot;country&quot; due to observedAttributes</c->
    <c- k>this</c-><c- p>.</c->_countryCode <c- o>=</c-> newValue<c- p>;</c->
    <c- k>this</c-><c- p>.</c->_updateRendering<c- p>();</c->
  <c- p>}</c->
  connectedCallback<c- p>()</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->_updateRendering<c- p>();</c->
  <c- p>}</c->

  get country<c- p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>this</c-><c- p>.</c->_countryCode<c- p>;</c->
  <c- p>}</c->
  set country<c- p>(</c->v<c- p>)</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->setAttribute<c- p>(</c-><c- u>&quot;country&quot;</c-><c- p>,</c-> v<c- p>);</c->
  <c- p>}</c->

  _updateRendering<c- p>()</c-> <c- p>{</c->
    <c- c1>// Left as an exercise for the reader. But, you&apos;ll probably want to</c->
    <c- c1>// check this.ownerDocument.defaultView to see if we&apos;ve been</c->
    <c- c1>// inserted into a document with a browsing context, and avoid</c->
    <c- c1>// doing any work if not.</c->
  <c- p>}</c->
<c- p>}</c-></code></pre>

  <p>We then need to use this class to define the element:</p>

  <pre><code class='js'>customElements<c- p>.</c->define<c- p>(</c-><c- u>&quot;flag-icon&quot;</c-><c- p>,</c-> FlagIcon<c- p>);</c-></code></pre>

  <p>At this point, our above code will work! The parser, whenever it sees the <code>flag-icon</code> tag, will construct a new instance of our <code>FlagIcon</code> class, and tell our code about its new <code>country</code>
  attribute, which we then use to set the element's internal state and update its rendering (when
  appropriate).</p>

  <p>You can also create <code>flag-icon</code> elements using the DOM API:</p>

  <pre><code class='js'><c- a>const</c-> flagIcon <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- u>&quot;flag-icon&quot;</c-><c- p>)</c->
flagIcon<c- p>.</c->country <c- o>=</c-> <c- u>&quot;jp&quot;</c->
document<c- p>.</c->body<c- p>.</c->appendChild<c- p>(</c->flagIcon<c- p>)</c-></code></pre>

  <p>Finally, we can also use the <a href=#custom-element-constructor id=custom-elements-autonomous-example:custom-element-constructor>custom element constructor</a> itself. That is, the above
  code is equivalent to:</p>

  <pre><code class='js'><c- a>const</c-> flagIcon <c- o>=</c-> <c- k>new</c-> FlagIcon<c- p>()</c->
flagIcon<c- p>.</c->country <c- o>=</c-> <c- u>&quot;jp&quot;</c->
document<c- p>.</c->body<c- p>.</c->appendChild<c- p>(</c->flagIcon<c- p>)</c-></code></pre>

  <h5 id=custom-elements-face-example><span class=secno>4.13.1.2</span> Creating a form-associated custom element<a href=#custom-elements-face-example class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>Adding a static <code>formAssociated</code> property, with a true value, makes an
  <a href=#autonomous-custom-element id=custom-elements-face-example:autonomous-custom-element>autonomous custom element</a> a <a href=#form-associated-custom-element id=custom-elements-face-example:form-associated-custom-element>form-associated custom element</a>. The
  <code id=custom-elements-face-example:elementinternals><a href=#elementinternals>ElementInternals</a></code> interface helps you to implement functions and properties common
  to form control elements.</p>

  <pre><code class='js'><c- a>class</c-> MyCheckbox <c- k>extends</c-> HTMLElement <c- p>{</c->
  <c- k>static</c-> formAssociated <c- o>=</c-> <c- kc>true</c-><c- p>;</c->
  <c- k>static</c-> observedAttributes <c- o>=</c-> <c- p>[</c-><c- t>&apos;checked&apos;</c-><c- p>];</c->

  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->
    <c- k>this</c-><c- p>.</c->_internals <c- o>=</c-> <c- k>this</c-><c- p>.</c->attachInternals<c- p>();</c->
    <c- k>this</c-><c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;click&apos;</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->_onClick<c- p>.</c->bind<c- p>(</c-><c- k>this</c-><c- p>));</c->
  <c- p>}</c->

  get form<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->form<c- p>;</c-> <c- p>}</c->
  get name<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->getAttribute<c- p>(</c-><c- t>&apos;name&apos;</c-><c- p>);</c-> <c- p>}</c->
  get type<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->localName<c- p>;</c-> <c- p>}</c->

  get checked<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->hasAttribute<c- p>(</c-><c- t>&apos;checked&apos;</c-><c- p>);</c-> <c- p>}</c->
  set checked<c- p>(</c->flag<c- p>)</c-> <c- p>{</c-> <c- k>this</c-><c- p>.</c->toggleAttribute<c- p>(</c-><c- t>&apos;checked&apos;</c-><c- p>,</c-> Boolean<c- p>(</c->flag<c- p>));</c-> <c- p>}</c->

  attributeChangedCallback<c- p>(</c->name<c- p>,</c-> oldValue<c- p>,</c-> newValue<c- p>)</c-> <c- p>{</c->
    <c- c1>// name will always be &quot;checked&quot; due to observedAttributes</c->
    <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->setFormValue<c- p>(</c-><c- k>this</c-><c- p>.</c->checked <c- o>?</c-> <c- t>&apos;on&apos;</c-> <c- o>:</c-> <c- kc>null</c-><c- p>);</c->
  <c- p>}</c->

  _onClick<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->checked <c- o>=</c-> <c- o>!</c-><c- k>this</c-><c- p>.</c->checked<c- p>;</c->
  <c- p>}</c->
<c- p>}</c->
customElements<c- p>.</c->define<c- p>(</c-><c- t>&apos;my-checkbox&apos;</c-><c- p>,</c-> MyCheckbox<c- p>);</c-></code></pre>

  <p>You can use the custom element <code>my-checkbox</code> like a built-in
  form-associated element. For example, putting it in <code id=custom-elements-face-example:the-form-element><a href=forms.html#the-form-element>form</a></code> or <code id=custom-elements-face-example:the-label-element><a href=forms.html#the-label-element>label</a></code>
  associates the <code>my-checkbox</code> element with them, and submitting the
  <code id=custom-elements-face-example:the-form-element-2><a href=forms.html#the-form-element>form</a></code> will send data provided by <code>my-checkbox</code> implementation.
  </p>

  <pre><code class='html'><c- p>&lt;</c-><c- f>form</c-> <c- e>action</c-><c- o>=</c-><c- s>&quot;...&quot;</c-> <c- e>method</c-><c- o>=</c-><c- s>&quot;...&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>label</c-><c- p>&gt;&lt;</c-><c- f>my-checkbox</c-> <c- e>name</c-><c- o>=</c-><c- s>&quot;agreed&quot;</c-><c- p>&gt;&lt;/</c-><c- f>my-checkbox</c-><c- p>&gt;</c-> I read the agreement.<c- p>&lt;/</c-><c- f>label</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>input</c-> <c- e>type</c-><c- o>=</c-><c- s>&quot;submit&quot;</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>form</c-><c- p>&gt;</c->
</code></pre>

  <h5 id=custom-elements-accessibility-example><span class=secno>4.13.1.3</span> Creating a custom element with default accessible roles, states, and properties<a href=#custom-elements-accessibility-example class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>By using the appropriate properties of <code id=custom-elements-accessibility-example:elementinternals><a href=#elementinternals>ElementInternals</a></code>, your custom element can
  have default accessibility semantics. The following code expands our form-associated checkbox from
  the previous section to properly set its default role and checkedness, as viewed by accessibility
  technology:</p>

  <pre><code class='js'><c- a>class</c-> MyCheckbox <c- k>extends</c-> HTMLElement <c- p>{</c->
  <c- k>static</c-> formAssociated <c- o>=</c-> <c- kc>true</c-><c- p>;</c->
  <c- k>static</c-> observedAttributes <c- o>=</c-> <c- p>[</c-><c- t>&apos;checked&apos;</c-><c- p>];</c->

  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->
    <c- k>this</c-><c- p>.</c->_internals <c- o>=</c-> <c- k>this</c-><c- p>.</c->attachInternals<c- p>();</c->
    <c- k>this</c-><c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;click&apos;</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->_onClick<c- p>.</c->bind<c- p>(</c-><c- k>this</c-><c- p>));</c->

<mark>    <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->role <c- o>=</c-> <c- t>&apos;checkbox&apos;</c-><c- p>;</c->
    <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->ariaChecked <c- o>=</c-> <c- t>&apos;false&apos;</c-><c- p>;</c-></mark>
  <c- p>}</c->

  get form<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->form<c- p>;</c-> <c- p>}</c->
  get name<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->getAttribute<c- p>(</c-><c- t>&apos;name&apos;</c-><c- p>);</c-> <c- p>}</c->
  get type<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->localName<c- p>;</c-> <c- p>}</c->

  get checked<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->hasAttribute<c- p>(</c-><c- t>&apos;checked&apos;</c-><c- p>);</c-> <c- p>}</c->
  set checked<c- p>(</c->flag<c- p>)</c-> <c- p>{</c-> <c- k>this</c-><c- p>.</c->toggleAttribute<c- p>(</c-><c- t>&apos;checked&apos;</c-><c- p>,</c-> Boolean<c- p>(</c->flag<c- p>));</c-> <c- p>}</c->

  attributeChangedCallback<c- p>(</c->name<c- p>,</c-> oldValue<c- p>,</c-> newValue<c- p>)</c-> <c- p>{</c->
    <c- c1>// name will always be &quot;checked&quot; due to observedAttributes</c->
    <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->setFormValue<c- p>(</c-><c- k>this</c-><c- p>.</c->checked <c- o>?</c-> <c- t>&apos;on&apos;</c-> <c- o>:</c-> <c- kc>null</c-><c- p>);</c->
<mark>    <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->ariaChecked <c- o>=</c-> <c- k>this</c-><c- p>.</c->checked<c- p>;</c-></mark>
  <c- p>}</c->

  _onClick<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->checked <c- o>=</c-> <c- o>!</c-><c- k>this</c-><c- p>.</c->checked<c- p>;</c->
  <c- p>}</c->
<c- p>}</c->
customElements<c- p>.</c->define<c- p>(</c-><c- t>&apos;my-checkbox&apos;</c-><c- p>,</c-> MyCheckbox<c- p>);</c-></code></pre>

  <p>Note that, like for built-in elements, these are only defaults, and can be overridden by the
  page author using the <code id=custom-elements-accessibility-example:attr-aria-role><a href=infrastructure.html#attr-aria-role>role</a></code> and <code id=custom-elements-accessibility-example:attr-aria-*><a href=infrastructure.html#attr-aria-*>aria-*</a></code> attributes:</p>

  <pre class=bad><code class='html'><c- c>&lt;!-- This markup is non-conforming --&gt;</c->
<c- p>&lt;</c-><c- f>input</c-> <c- e>type</c-><c- o>=</c-><c- s>&quot;checkbox&quot;</c-> <c- e>checked</c-> <c- e>role</c-><c- o>=</c-><c- s>&quot;button&quot;</c-> <c- e>aria-checked</c-><c- o>=</c-><c- s>&quot;false&quot;</c-><c- p>&gt;</c-></code></pre>

<pre class=bad><code class='html'><c- c>&lt;!-- This markup is probably not what the custom element author intended --&gt;</c->
<c- p>&lt;</c-><c- f>my-checkbox</c-> <c- e>role</c-><c- o>=</c-><c- s>&quot;button&quot;</c-> <c- e>checked</c-> <c- e>aria-checked</c-><c- o>=</c-><c- s>&quot;false&quot;</c-><c- p>&gt;</c-></code></pre>

  <p>Custom element authors are encouraged to state what aspects of their accessibility semantics
  are strong native semantics, i.e., should not be overridden by users of the custom element. In our
  example, the author of the <code>my-checkbox</code> element would state that its
  <a id=custom-elements-accessibility-example:role href=https://w3c.github.io/aria/#dfn-role data-x-internal=role>role</a> and <code id=custom-elements-accessibility-example:attr-aria-checked><a data-x-internal=attr-aria-checked href=https://w3c.github.io/aria/#aria-checked>aria-checked</a></code> values are strong
  native semantics, thus discouraging code such as the above.</p>

  <h5 id=custom-elements-customized-builtin-example><span class=secno>4.13.1.4</span> Creating a customized built-in element<a href=#custom-elements-customized-builtin-example class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p><a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element>Customized built-in elements</a> are a distinct
  kind of <a href=#custom-element id=custom-elements-customized-builtin-example:custom-element>custom element</a>, which are defined slightly differently and used very
  differently compared to <a href=#autonomous-custom-element id=custom-elements-customized-builtin-example:autonomous-custom-element>autonomous custom
  elements</a>. They exist to allow reuse of behaviors from the existing elements of HTML, by
  extending those elements with new custom functionality. This is important since many of the
  existing behaviors of HTML elements can unfortunately not be duplicated by using purely <a href=#autonomous-custom-element id=custom-elements-customized-builtin-example:autonomous-custom-element-2>autonomous custom elements</a>. Instead, <a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-2>customized built-in elements</a> allow the installation of
  custom construction behavior, lifecycle hooks, and prototype chain onto existing elements,
  essentially "mixing in" these capabilities on top of the already-existing element.</p>

  <p><a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-3>Customized built-in elements</a> require a
  distinct syntax from <a href=#autonomous-custom-element id=custom-elements-customized-builtin-example:autonomous-custom-element-3>autonomous custom elements</a>
  because user agents and other software key off an element's local name in order to identify the
  element's semantics and behavior. That is, the concept of <a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-4>customized built-in elements</a> building on top of existing behavior depends
  crucially on the extended elements retaining their original local name.</p>

  <p>In this example, we'll be creating a <a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-5>customized built-in element</a> named <code>plastic-button</code>, which behaves like a normal button but gets fancy animation
  effects added whenever you click on it. We start by defining a class, just like before, although
  this time we extend <code id=custom-elements-customized-builtin-example:htmlbuttonelement><a href=form-elements.html#htmlbuttonelement>HTMLButtonElement</a></code> instead of <code id=custom-elements-customized-builtin-example:htmlelement><a href=dom.html#htmlelement>HTMLElement</a></code>:</p>

  <pre><code class='js'><c- a>class</c-> PlasticButton <c- k>extends</c-> HTMLButtonElement <c- p>{</c->
  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->

    <c- k>this</c-><c- p>.</c->addEventListener<c- p>(</c-><c- u>&quot;click&quot;</c-><c- p>,</c-> <c- p>()</c-> <c- p>=&gt;</c-> <c- p>{</c->
      <c- c1>// Draw some fancy animation effects!</c->
    <c- p>});</c->
  <c- p>}</c->
<c- p>}</c-></code></pre>

  <p>When defining our custom element, we have to also specify the <code id=custom-elements-customized-builtin-example:dom-elementdefinitionoptions-extends><a href=#dom-elementdefinitionoptions-extends>extends</a></code> option:</p>

  <pre><code class='js'>customElements<c- p>.</c->define<c- p>(</c-><c- u>&quot;plastic-button&quot;</c-><c- p>,</c-> PlasticButton<c- p>,</c-> <c- p>{</c-> <c- k>extends</c-><c- o>:</c-> <c- u>&quot;button&quot;</c-> <c- p>});</c-></code></pre>

  <p>In general, the name of the element being extended cannot be determined simply by looking at
  what element interface it extends, as many elements share the same interface (such as
  <code id=custom-elements-customized-builtin-example:the-q-element><a href=text-level-semantics.html#the-q-element>q</a></code> and <code id=custom-elements-customized-builtin-example:the-blockquote-element><a href=grouping-content.html#the-blockquote-element>blockquote</a></code> both sharing <code id=custom-elements-customized-builtin-example:htmlquoteelement><a href=grouping-content.html#htmlquoteelement>HTMLQuoteElement</a></code>).</p>

  <p>To construct our <a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-6>customized built-in element</a> from parsed HTML source text, we use
  the <code id=custom-elements-customized-builtin-example:attr-is><a href=#attr-is>is</a></code> attribute on a <code id=custom-elements-customized-builtin-example:the-button-element><a href=form-elements.html#the-button-element>button</a></code> element:</p>

  <pre><code class='html'><c- p>&lt;</c-><c- f>button</c-> <c- e>is</c-><c- o>=</c-><c- s>&quot;plastic-button&quot;</c-><c- p>&gt;</c->Click Me!<c- p>&lt;/</c-><c- f>button</c-><c- p>&gt;</c-></code></pre>

  <p>Trying to use a <a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-7>customized built-in element</a> as an <a href=#autonomous-custom-element id=custom-elements-customized-builtin-example:autonomous-custom-element-4>autonomous custom
  element</a> will <em>not</em> work; that is, <code>&lt;plastic-button>Click
  me?&lt;/plastic-button></code> will simply create an <code id=custom-elements-customized-builtin-example:htmlelement-2><a href=dom.html#htmlelement>HTMLElement</a></code> with no special
  behavior.</p>

  <p>If you need to create a customized built-in element programmatically, you can use the following
  form of <code id=custom-elements-customized-builtin-example:dom-document-createelement><a data-x-internal=dom-document-createelement href=https://dom.spec.whatwg.org/#dom-document-createelement>createElement()</a></code>:</p>

  <pre><code class='js'><c- a>const</c-> plasticButton <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- u>&quot;button&quot;</c-><c- p>,</c-> <c- p>{</c-> is<c- o>:</c-> <c- u>&quot;plastic-button&quot;</c-> <c- p>});</c->
plasticButton<c- p>.</c->textContent <c- o>=</c-> <c- u>&quot;Click me!&quot;</c-><c- p>;</c-></code></pre>

  <p>And as before, the constructor will also work:</p>

  <pre><code class='js'><c- a>const</c-> plasticButton2 <c- o>=</c-> <c- k>new</c-> PlasticButton<c- p>();</c->
console<c- p>.</c->log<c- p>(</c->plasticButton2<c- p>.</c->localName<c- p>);</c->  <c- c1>// will output &quot;button&quot;</c->
console<c- p>.</c->assert<c- p>(</c->plasticButton2 <c- k>instanceof</c-> PlasticButton<c- p>);</c->
console<c- p>.</c->assert<c- p>(</c->plasticButton2 <c- k>instanceof</c-> HTMLButtonElement<c- p>);</c-></code></pre>

  <p>Note that when creating a customized built-in element programmatically, the <code id=custom-elements-customized-builtin-example:attr-is-2><a href=#attr-is>is</a></code> attribute will not be present in the DOM, since it was not explicitly
  set. However, <a href=parsing.html#attr-is-during-serialization>it will be added to the output when
  serializing</a>:</p>

  <pre><code class='js'>console<c- p>.</c->assert<c- p>(</c-><c- o>!</c->plasticButton<c- p>.</c->hasAttribute<c- p>(</c-><c- u>&quot;is&quot;</c-><c- p>));</c->
console<c- p>.</c->log<c- p>(</c->plasticButton<c- p>.</c->outerHTML<c- p>);</c-> <c- c1>// will output &apos;&lt;button is=&quot;plastic-button&quot;&gt;&lt;/button&gt;&apos;</c-></code></pre>

  <p>Regardless of how it is created, all of the ways in which <code id=custom-elements-customized-builtin-example:the-button-element-2><a href=form-elements.html#the-button-element>button</a></code> is special
  apply to such "plastic buttons" as well: their focus behavior, ability to participate in <a href=form-control-infrastructure.html#concept-form-submit id=custom-elements-customized-builtin-example:concept-form-submit>form submission</a>, the <code id=custom-elements-customized-builtin-example:attr-fe-disabled><a href=form-control-infrastructure.html#attr-fe-disabled>disabled</a></code> attribute, and so on.</p>

  <p id=customized-built-in-element-restrictions><a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-8>Customized built-in elements</a> are designed to allow extension of existing HTML
  elements that have useful user-agent supplied behavior or APIs. As such, they can only extend
  existing HTML elements defined in this specification, and cannot extend legacy elements such as
  <code id=custom-elements-customized-builtin-example:bgsound><a href=obsolete.html#bgsound>bgsound</a></code>, <code id=custom-elements-customized-builtin-example:blink><a href=obsolete.html#blink>blink</a></code>, <code id=custom-elements-customized-builtin-example:isindex><a href=obsolete.html#isindex>isindex</a></code>, <code id=custom-elements-customized-builtin-example:keygen><a href=obsolete.html#keygen>keygen</a></code>,
  <code id=custom-elements-customized-builtin-example:multicol><a href=obsolete.html#multicol>multicol</a></code>, <code id=custom-elements-customized-builtin-example:nextid><a href=obsolete.html#nextid>nextid</a></code>, or <code id=custom-elements-customized-builtin-example:spacer><a href=obsolete.html#spacer>spacer</a></code> that have been defined to use
  <code id=custom-elements-customized-builtin-example:htmlunknownelement><a href=dom.html#htmlunknownelement>HTMLUnknownElement</a></code> as their <a id=custom-elements-customized-builtin-example:element-interface href=https://dom.spec.whatwg.org/#concept-element-interface data-x-internal=element-interface>element interface</a>.</p>

  <p>One reason for this requirement is future-compatibility: if a <a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-9>customized built-in
  element</a> was defined that extended a currently-unknown element, for example <code>combobox</code>, this would prevent this specification from defining a <code>combobox</code> element in the future, as consumers of the derived <a href=#customized-built-in-element id=custom-elements-customized-builtin-example:customized-built-in-element-10>customized
  built-in element</a> would have come to depend on their base element having no interesting
  user-agent-supplied behavior.</p>

  <h5 id=custom-elements-autonomous-drawbacks><span class=secno>4.13.1.5</span> Drawbacks of autonomous custom elements<a href=#custom-elements-autonomous-drawbacks class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>As specified below, and alluded to above, simply defining and using an element called
  <code>taco-button</code> does not mean that such elements <a href=dom.html#represents id=custom-elements-autonomous-drawbacks:represents>represent</a> buttons. That is, tools such as web browsers, search engines,
  or accessibility technology will not automatically treat the resulting element as a button just
  based on its defined name.</p>

  <p>To convey the desired button semantics to a variety of users, while still using an
  <a href=#autonomous-custom-element id=custom-elements-autonomous-drawbacks:autonomous-custom-element>autonomous custom element</a>, a number of techniques would need to be employed:</p>

  <ul><li><p>The addition of the <code id=custom-elements-autonomous-drawbacks:attr-tabindex><a href=interaction.html#attr-tabindex>tabindex</a></code> attribute would make the
   <code>taco-button</code> <a id=custom-elements-autonomous-drawbacks:focusable href=interaction.html#focusable>focusable</a>. Note that if the
   <code>taco-button</code> were to become logically disabled, the <code id=custom-elements-autonomous-drawbacks:attr-tabindex-2><a href=interaction.html#attr-tabindex>tabindex</a></code> attribute would need to be removed.<li><p>The addition of an ARIA role and various ARIA states and properties helps convey semantics
   to accessibility technology. For example, setting the <a id=custom-elements-autonomous-drawbacks:role href=https://w3c.github.io/aria/#dfn-role data-x-internal=role>role</a> to "<code id=custom-elements-autonomous-drawbacks:attr-aria-role-button><a data-x-internal=attr-aria-role-button href=https://w3c.github.io/aria/#button>button</a></code>" will convey the semantics that this is a button,
   enabling users to successfully interact with the control using usual button-like interactions in
   their accessibility technology. Setting the <code id=custom-elements-autonomous-drawbacks:attr-aria-label><a data-x-internal=attr-aria-label href=https://w3c.github.io/aria/#aria-label>aria-label</a></code>
   property is necessary to give the button an <a href=https://w3c.github.io/aria/#dfn-accessible-name id=custom-elements-autonomous-drawbacks:concept-accessible-name data-x-internal=concept-accessible-name>accessible
   name</a>, instead of having accessibility technology traverse its child text nodes and
   announce them. And setting the <code id=custom-elements-autonomous-drawbacks:attr-aria-disabled><a data-x-internal=attr-aria-disabled href=https://w3c.github.io/aria/#aria-disabled>aria-disabled</a></code> state to
   "<code>true</code>" when the button is logically disabled conveys to accessibility
   technology the button's disabled state.<li><p>The addition of event handlers to handle commonly-expected button behaviors helps convey
   the semantics of the button to web browser users. In this case, the most relevant event handler
   would be one that proxies appropriate <code id=custom-elements-autonomous-drawbacks:event-keydown><a data-x-internal=event-keydown href=https://w3c.github.io/uievents/#event-type-keydown>keydown</a></code> events to
   become <code id=custom-elements-autonomous-drawbacks:event-click><a data-x-internal=event-click href=https://w3c.github.io/uievents/#event-type-click>click</a></code> events, so that you can activate the button both
   with keyboard and by clicking.<li><p>In addition to any default visual styling provided for <code>taco-button</code>
   elements, the visual styling will also need to be updated to reflect changes in logical state,
   such as becoming disabled; that is, whatever style sheet has rules for <code>taco-button</code> will also need to have rules for <code>taco-button[disabled]</code>.</ul>

  <p>With these points in mind, a full-featured <code>taco-button</code> that took on the
  responsibility of conveying button semantics (including the ability to be disabled) might look
  something like this:</p>

  <pre id=custom-elements-autonomous-drawbacks-example><code class='js'><c- a>class</c-> TacoButton <c- k>extends</c-> HTMLElement <c- p>{</c->
  <c- k>static</c-> observedAttributes <c- o>=</c-> <c- p>[</c-><c- u>&quot;disabled&quot;</c-><c- p>];</c->

  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->
    <c- k>this</c-><c- p>.</c->_internals <c- o>=</c-> <c- k>this</c-><c- p>.</c->attachInternals<c- p>();</c->
    <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->role <c- o>=</c-> <c- u>&quot;button&quot;</c-><c- p>;</c->

    <c- k>this</c-><c- p>.</c->addEventListener<c- p>(</c-><c- u>&quot;keydown&quot;</c-><c- p>,</c-> e <c- p>=&gt;</c-> <c- p>{</c->
      <c- k>if</c-> <c- p>(</c->e<c- p>.</c->code <c- o>===</c-> <c- u>&quot;Enter&quot;</c-> <c- o>||</c-> e<c- p>.</c->code <c- o>===</c-> <c- u>&quot;Space&quot;</c-><c- p>)</c-> <c- p>{</c->
        <c- k>this</c-><c- p>.</c->dispatchEvent<c- p>(</c-><c- k>new</c-> PointerEvent<c- p>(</c-><c- u>&quot;click&quot;</c-><c- p>,</c-> <c- p>{</c->
          bubbles<c- o>:</c-> <c- kc>true</c-><c- p>,</c->
          cancelable<c- o>:</c-> <c- kc>true</c->
        <c- p>}));</c->
      <c- p>}</c->
    <c- p>});</c->

    <c- k>this</c-><c- p>.</c->addEventListener<c- p>(</c-><c- u>&quot;click&quot;</c-><c- p>,</c-> e <c- p>=&gt;</c-> <c- p>{</c->
      <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->disabled<c- p>)</c-> <c- p>{</c->
        e<c- p>.</c->preventDefault<c- p>();</c->
        e<c- p>.</c->stopImmediatePropagation<c- p>();</c->
      <c- p>}</c->
    <c- p>});</c->

    <c- k>this</c-><c- p>.</c->_observer <c- o>=</c-> <c- k>new</c-> MutationObserver<c- p>(()</c-> <c- p>=&gt;</c-> <c- p>{</c->
      <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->ariaLabel <c- o>=</c-> <c- k>this</c-><c- p>.</c->textContent<c- p>;</c->
    <c- p>});</c->
  <c- p>}</c->

  connectedCallback<c- p>()</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->setAttribute<c- p>(</c-><c- u>&quot;tabindex&quot;</c-><c- p>,</c-> <c- u>&quot;0&quot;</c-><c- p>);</c->

    <c- k>this</c-><c- p>.</c->_observer<c- p>.</c->observe<c- p>(</c-><c- k>this</c-><c- p>,</c-> <c- p>{</c->
      childList<c- o>:</c-> <c- kc>true</c-><c- p>,</c->
      characterData<c- o>:</c-> <c- kc>true</c-><c- p>,</c->
      subtree<c- o>:</c-> <c- kc>true</c->
    <c- p>});</c->
  <c- p>}</c->

  disconnectedCallback<c- p>()</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->_observer<c- p>.</c->disconnect<c- p>();</c->
  <c- p>}</c->

  get disabled<c- p>()</c-> <c- p>{</c->
    <c- k>return</c-> <c- k>this</c-><c- p>.</c->hasAttribute<c- p>(</c-><c- u>&quot;disabled&quot;</c-><c- p>);</c->
  <c- p>}</c->
  set disabled<c- p>(</c->flag<c- p>)</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->toggleAttribute<c- p>(</c-><c- u>&quot;disabled&quot;</c-><c- p>,</c-> Boolean<c- p>(</c->flag<c- p>));</c->
  <c- p>}</c->

  attributeChangedCallback<c- p>(</c->name<c- p>,</c-> oldValue<c- p>,</c-> newValue<c- p>)</c-> <c- p>{</c->
    <c- c1>// name will always be &quot;disabled&quot; due to observedAttributes</c->
    <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->disabled<c- p>)</c-> <c- p>{</c->
      <c- k>this</c-><c- p>.</c->removeAttribute<c- p>(</c-><c- u>&quot;tabindex&quot;</c-><c- p>);</c->
      <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->ariaDisabled <c- o>=</c-> <c- u>&quot;true&quot;</c-><c- p>;</c->
    <c- p>}</c-> <c- k>else</c-> <c- p>{</c->
      <c- k>this</c-><c- p>.</c->setAttribute<c- p>(</c-><c- u>&quot;tabindex&quot;</c-><c- p>,</c-> <c- u>&quot;0&quot;</c-><c- p>);</c->
      <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->ariaDisabled <c- o>=</c-> <c- u>&quot;false&quot;</c-><c- p>;</c->
    <c- p>}</c->
  <c- p>}</c->
<c- p>}</c-></code></pre>

  <p>Even with this rather-complicated element definition, the element is not a pleasure to use for
  consumers: it will be continually "sprouting" <code id=custom-elements-autonomous-drawbacks:attr-tabindex-3><a href=interaction.html#attr-tabindex>tabindex</a></code>
  attributes of its own volition, and its choice of <code>tabindex="0"</code> focusability
  behavior may not match the <code id=custom-elements-autonomous-drawbacks:the-button-element><a href=form-elements.html#the-button-element>button</a></code> behavior on the current platform. This is because
  as of now there is no way to specify default focus behavior for custom elements, forcing the use
  of the <code id=custom-elements-autonomous-drawbacks:attr-tabindex-4><a href=interaction.html#attr-tabindex>tabindex</a></code> attribute to do so (even though it is usually
  reserved for allowing the consumer to override default behavior).</p>

  <p>In contrast, a simple <a href=#customized-built-in-element id=custom-elements-autonomous-drawbacks:customized-built-in-element>customized built-in element</a>, as shown in the previous
  section, would automatically inherit the semantics and behavior of the <code id=custom-elements-autonomous-drawbacks:the-button-element-2><a href=form-elements.html#the-button-element>button</a></code>
  element, with no need to implement these behaviors manually. In general, for any elements with
  nontrivial behavior and semantics that build on top of existing elements of HTML, <a href=#customized-built-in-element id=custom-elements-autonomous-drawbacks:customized-built-in-element-2>customized built-in elements</a> will be easier to
  develop, maintain, and consume.</p>

  <h5 id=custom-elements-upgrades-examples><span class=secno>4.13.1.6</span> Upgrading elements after their creation<a href=#custom-elements-upgrades-examples class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>Because <a href=#element-definition id=custom-elements-upgrades-examples:element-definition>element definition</a> can occur at any time, a non-custom element could be
  <a href=https://dom.spec.whatwg.org/#concept-create-element id=custom-elements-upgrades-examples:create-an-element data-x-internal=create-an-element>created</a>, and then later become a <a href=#custom-element id=custom-elements-upgrades-examples:custom-element>custom
  element</a> after an appropriate <a href=#custom-element-definition id=custom-elements-upgrades-examples:custom-element-definition>definition</a> is
  registered. We call this process "upgrading" the element, from a normal element into a custom
  element.</p>

  <p><a href=#upgrades id=custom-elements-upgrades-examples:upgrades>Upgrades</a> enable scenarios where it may be
  preferable for <a href=#custom-element-definition id=custom-elements-upgrades-examples:custom-element-definition-2>custom element definitions</a> to be
  registered after relevant elements have been initially created, such as by the parser. They allow
  progressive enhancement of the content in the custom element. For example, in the following HTML
  document the element definition for <code>img-viewer</code> is loaded
  asynchronously:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE html&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Image viewer example<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>img-viewer</c-> <c- e>filter</c-><c- o>=</c-><c- s>&quot;Kelvin&quot;</c-><c- p>&gt;</c->
  <c- p>&lt;</c-><c- f>img</c-> <c- e>src</c-><c- o>=</c-><c- s>&quot;images/tree.jpg&quot;</c-> <c- e>alt</c-><c- o>=</c-><c- s>&quot;A beautiful tree towering over an empty savannah&quot;</c-><c- p>&gt;</c->
<c- p>&lt;/</c-><c- f>img-viewer</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>script</c-> <c- e>src</c-><c- o>=</c-><c- s>&quot;js/elements/img-viewer.js&quot;</c-> <c- e>async</c-><c- p>&gt;&lt;/</c-><c- f>script</c-><c- p>&gt;</c-></code></pre>

  <p>The definition for the <code>img-viewer</code> element here is loaded using a
  <code id=custom-elements-upgrades-examples:the-script-element><a href=scripting.html#the-script-element>script</a></code> element marked with the <code id=custom-elements-upgrades-examples:attr-script-async><a href=scripting.html#attr-script-async>async</a></code>
  attribute, placed after the <code>&lt;img-viewer></code> tag in the markup. While the
  script is loading, the <code>img-viewer</code> element will be treated as an undefined
  element, similar to a <code id=custom-elements-upgrades-examples:the-span-element><a href=text-level-semantics.html#the-span-element>span</a></code>. Once the script loads, it will define the <code>img-viewer</code> element, and the existing <code>img-viewer</code> element on
  the page will be upgraded, applying the custom element's definition (which presumably includes
  applying an image filter identified by the string "Kelvin", enhancing the image's visual
  appearance).</p>

  <hr>

  <p>Note that <a href=#upgrades id=custom-elements-upgrades-examples:upgrades-2>upgrades</a> only apply to elements in the
  document tree. (Formally, elements that are <a id=custom-elements-upgrades-examples:connected href=https://dom.spec.whatwg.org/#connected data-x-internal=connected>connected</a>.) An element that is not
  inserted into a document will stay un-upgraded. An example illustrates this point:</p>

  <pre><code class='html'><c- cp>&lt;!DOCTYPE html&gt;</c->
<c- p>&lt;</c-><c- f>html</c-> <c- e>lang</c-><c- o>=</c-><c- s>&quot;en&quot;</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>title</c-><c- p>&gt;</c->Upgrade edge-cases example<c- p>&lt;/</c-><c- f>title</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>example-element</c-><c- p>&gt;&lt;/</c-><c- f>example-element</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
  <c- u>&quot;use strict&quot;</c-><c- p>;</c->

  <c- a>const</c-> inDocument <c- o>=</c-> document<c- p>.</c->querySelector<c- p>(</c-><c- u>&quot;example-element&quot;</c-><c- p>);</c->
  <c- a>const</c-> outOfDocument <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- u>&quot;example-element&quot;</c-><c- p>);</c->

  <c- c1>// Before the element definition, both are HTMLElement:</c->
  console<c- p>.</c->assert<c- p>(</c->inDocument <c- k>instanceof</c-> HTMLElement<c- p>);</c->
  console<c- p>.</c->assert<c- p>(</c->outOfDocument <c- k>instanceof</c-> HTMLElement<c- p>);</c->

  <c- a>class</c-> ExampleElement <c- k>extends</c-> HTMLElement <c- p>{}</c->
  customElements<c- p>.</c->define<c- p>(</c-><c- u>&quot;example-element&quot;</c-><c- p>,</c-> ExampleElement<c- p>);</c->

  <c- c1>// After element definition, the in-document element was upgraded:</c->
  console<c- p>.</c->assert<c- p>(</c->inDocument <c- k>instanceof</c-> ExampleElement<c- p>);</c->
  console<c- p>.</c->assert<c- p>(</c-><c- o>!</c-><c- p>(</c->outOfDocument <c- k>instanceof</c-> ExampleElement<c- p>));</c->

  document<c- p>.</c->body<c- p>.</c->appendChild<c- p>(</c->outOfDocument<c- p>);</c->

  <c- c1>// Now that we&apos;ve moved the element into the document, it too was upgraded:</c->
  console<c- p>.</c->assert<c- p>(</c->outOfDocument <c- k>instanceof</c-> ExampleElement<c- p>);</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c-></code></pre>

  <h5 id=scoped-custom-element-registries><span class=secno>4.13.1.7</span> Scoped custom element registries<a href=#scoped-custom-element-registries class=self-link></a></h5>

  <p>To allow multiple libraries to co-exist without explicit coordination,
  <code id=scoped-custom-element-registries:customelementregistry><a href=#customelementregistry>CustomElementRegistry</a></code> can be used in a scoped fashion as well.</p>

  <pre><code class='js'><c- a>const</c-> scoped <c- o>=</c-> <c- k>new</c-> CustomElementRegistry<c- p>();</c->
scoped<c- p>.</c->define<c- p>(</c-><c- u>&quot;example-element&quot;</c-><c- p>,</c-> ExampleElement<c- p>);</c->

<c- a>const</c-> element <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- u>&quot;example-element&quot;</c-><c- p>,</c-> <c- p>{</c-> customElementRegistry<c- o>:</c-> scoped <c- p>});</c-></code></pre>

  <p>A node with an associated scoped <code id=scoped-custom-element-registries:customelementregistry-2><a href=#customelementregistry>CustomElementRegistry</a></code> will use that registry for
  all its operations, such as when invoking <code id=scoped-custom-element-registries:dom-element-sethtmlunsafe><a href=dynamic-markup-insertion.html#dom-element-sethtmlunsafe>setHTMLUnsafe()</a></code>.</p>

  <h5 id=exposing-custom-element-states><span class=secno>4.13.1.8</span> Exposing custom element states<a href=#exposing-custom-element-states class=self-link></a></h5>

  <p>Built-in elements provided by user agents have certain states that can change over time
  depending on user interaction and other factors, and are exposed to web authors through <a href=https://drafts.csswg.org/selectors/#pseudo-class id=exposing-custom-element-states:pseudo-class data-x-internal=pseudo-class>pseudo-classes</a>. For example, some form controls have the "invalid"
  state, which is exposed through the <code id=exposing-custom-element-states:selector-invalid><a href=semantics-other.html#selector-invalid>:invalid</a></code>
  <a id=exposing-custom-element-states:pseudo-class-2 href=https://drafts.csswg.org/selectors/#pseudo-class data-x-internal=pseudo-class>pseudo-class</a>.</p>

  <p>Like built-in elements, <a href=#custom-element id=exposing-custom-element-states:custom-element>custom elements</a> can have various
  states to be in too, and <a href=#custom-element id=exposing-custom-element-states:custom-element-2>custom element</a> authors want to expose these states in a
  similar fashion as the built-in elements.</p>

  <p>This is done via the <code id=exposing-custom-element-states:selector-custom><a href=semantics-other.html#selector-custom>:state()</a></code> pseudo-class. A custom
  element author can use the <code id=exposing-custom-element-states:dom-elementinternals-states><a href=#dom-elementinternals-states>states</a></code> property of
  <code id=exposing-custom-element-states:elementinternals><a href=#elementinternals>ElementInternals</a></code> to add and remove such custom states, which are then exposed as
  arguments to the <code id=exposing-custom-element-states:selector-custom-2><a href=semantics-other.html#selector-custom>:state()</a></code> pseudo-class.

  <div class=example>
   <p>The following shows how <code id=exposing-custom-element-states:selector-custom-3><a href=semantics-other.html#selector-custom>:state()</a></code> can be used to style a
   custom checkbox element. Assume that <code>LabeledCheckbox</code> doesn't expose its
   "checked" state via a content attribute.</p>

   <pre><code class='html'><c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
<c- a>class</c-> LabeledCheckbox <c- k>extends</c-> HTMLElement <c- p>{</c->
  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->
    <c- k>this</c-><c- p>.</c->_internals <c- o>=</c-> <c- k>this</c-><c- p>.</c->attachInternals<c- p>();</c->
    <c- k>this</c-><c- p>.</c->addEventListener<c- p>(</c-><c- t>&apos;click&apos;</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->_onClick<c- p>.</c->bind<c- p>(</c-><c- k>this</c-><c- p>));</c->

    <c- a>const</c-> shadowRoot <c- o>=</c-> <c- k>this</c-><c- p>.</c->attachShadow<c- p>({</c->mode<c- o>:</c-> <c- t>&apos;closed&apos;</c-><c- p>});</c->
    shadowRoot<c- p>.</c->innerHTML <c- o>=</c->
      <c- sb>`&lt;style&gt;</c->
<c- sb>       :host::before {</c->
<c- sb>         content: &apos;[ ]&apos;;</c->
<c- sb>         white-space: pre;</c->
<c- sb>         font-family: monospace;</c->
<c- sb>       }</c->
<c- sb>       :host(:state(checked))::before { content: &apos;[x]&apos; }</c->
<c- sb>       &lt;/style&gt;</c->
<c- sb>       &lt;slot&gt;Label&lt;/slot&gt;`</c-><c- p>;</c->
  <c- p>}</c->

  get checked<c- p>()</c-> <c- p>{</c-> <c- k>return</c-> <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->states<c- p>.</c->has<c- p>(</c-><c- t>&apos;checked&apos;</c-><c- p>);</c-> <c- p>}</c->

  set checked<c- p>(</c->flag<c- p>)</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c->flag<c- p>)</c->
      <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->states<c- p>.</c->add<c- p>(</c-><c- t>&apos;checked&apos;</c-><c- p>);</c->
    <c- k>else</c->
      <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->states<c- p>.</c-><c- k>delete</c-><c- p>(</c-><c- t>&apos;checked&apos;</c-><c- p>);</c->
  <c- p>}</c->

  _onClick<c- p>(</c->event<c- p>)</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->checked <c- o>=</c-> <c- o>!</c-><c- k>this</c-><c- p>.</c->checked<c- p>;</c->
  <c- p>}</c->
<c- p>}</c->

customElements<c- p>.</c->define<c- p>(</c-><c- t>&apos;labeled-checkbox&apos;</c-><c- p>,</c-> LabeledCheckbox<c- p>);</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>style</c-><c- p>&gt;</c->
<c- f>labeled-checkbox</c-> <c- p>{</c-> <c- k>border</c-><c- p>:</c-> <c- kc>dashed</c-> <c- kc>red</c-><c- p>;</c-> <c- p>}</c->
<c- f>labeled-checkbox</c-><c- p>:</c-><c- nd>state</c-><c- o>(</c-><c- f>checked</c-><c- o>)</c-> <c- p>{</c-> <c- k>border</c-><c- p>:</c-> <c- kc>solid</c-><c- p>;</c-> <c- p>}</c->
<c- p>&lt;/</c-><c- f>style</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>labeled-checkbox</c-><c- p>&gt;</c->You need to check this<c- p>&lt;/</c-><c- f>labeled-checkbox</c-><c- p>&gt;</c-></code></pre>
  </div>

  <div class=example>
   <p>Custom pseudo-classes can even target shadow parts. An extension of the above example shows
   this:</p>

   <pre><code class='html'><c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
<c- a>class</c-> QuestionBox <c- k>extends</c-> HTMLElement <c- p>{</c->
  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->
    <c- a>const</c-> shadowRoot <c- o>=</c-> <c- k>this</c-><c- p>.</c->attachShadow<c- p>({</c->mode<c- o>:</c-> <c- t>&apos;closed&apos;</c-><c- p>});</c->
    shadowRoot<c- p>.</c->innerHTML <c- o>=</c->
      <c- sb>`&lt;div&gt;&lt;slot&gt;Question&lt;/slot&gt;&lt;/div&gt;</c->
<c- sb>       &lt;labeled-checkbox part=&apos;checkbox&apos;&gt;Yes&lt;/labeled-checkbox&gt;`</c-><c- p>;</c->
  <c- p>}</c->
<c- p>}</c->
customElements<c- p>.</c->define<c- p>(</c-><c- t>&apos;question-box&apos;</c-><c- p>,</c-> QuestionBox<c- p>);</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>style</c-><c- p>&gt;</c->
<c- f>question-box</c-><c- p>::</c-><c- nd>part</c-><c- o>(</c-><c- f>checkbox</c-><c- o>)</c-> <c- p>{</c-> <c- k>color</c-><c- p>:</c-> <c- kc>red</c-><c- p>;</c-> <c- p>}</c->
<c- f>question-box</c-><c- p>::</c-><c- nd>part</c-><c- o>(</c-><c- f>checkbox</c-><c- o>)</c-><c- p>:</c-><c- nd>state</c-><c- o>(</c-><c- f>checked</c-><c- o>)</c-> <c- p>{</c-> <c- k>color</c-><c- p>:</c-> <c- kc>green</c-><c- p>;</c-> <c- p>}</c->
<c- p>&lt;/</c-><c- f>style</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>question-box</c-><c- p>&gt;</c->Continue?<c- p>&lt;/</c-><c- f>question-box</c-><c- p>&gt;</c-></code></pre>
  </div>

  <h4 id=custom-element-conformance><span class=secno>4.13.2</span> Requirements for custom element constructors and
  reactions<a href=#custom-element-conformance class=self-link></a></h4>

  <p>When authoring <a href=#custom-element-constructor id=custom-element-conformance:custom-element-constructor>custom element constructors</a>,
  authors are bound by the following conformance requirements:</p>

  <ul><li><p>A parameter-less call to <code>super()</code> must be the first statement in the
   constructor body, to establish the correct prototype chain and <b>this</b> value before any
   further code is run.<li><p>A <code>return</code> statement must not appear anywhere inside the constructor
   body, unless it is a simple early-return (<code>return</code> or <code>return
   this</code>).<li><p>The constructor must not use the <code id=custom-element-conformance:dom-document-write><a href=dynamic-markup-insertion.html#dom-document-write>document.write()</a></code>
   or <code id=custom-element-conformance:dom-document-open><a href=dynamic-markup-insertion.html#dom-document-open>document.open()</a></code> methods.<li><p>The element's attributes and children must not be inspected, as in the non-<a href=#upgrades id=custom-element-conformance:upgrades>upgrade</a> case none will be present, and relying on
   upgrades makes the element less usable.<li><p>The element must not gain any attributes or children, as this violates the expectations of
   consumers who use the <code id=custom-element-conformance:dom-document-createelement><a data-x-internal=dom-document-createelement href=https://dom.spec.whatwg.org/#dom-document-createelement>createElement</a></code> or <code id=custom-element-conformance:dom-document-createelementns><a data-x-internal=dom-document-createelementns href=https://dom.spec.whatwg.org/#dom-document-createelementns>createElementNS</a></code> methods.<li><p>In general, work should be deferred to <code>connectedCallback</code> as much as
   possible—especially work involving fetching resources or rendering. However, note that <code>connectedCallback</code> can be called more than once, so any initialization work that
   is truly one-time will need a guard to prevent it from running twice.<li><p>In general, the constructor should be used to set up initial state and default values, and
   to set up event listeners and possibly a <a id=custom-element-conformance:shadow-root href=https://dom.spec.whatwg.org/#concept-shadow-root data-x-internal=shadow-root>shadow root</a>.</ul>

  <p>Several of these requirements are checked during <a href=https://dom.spec.whatwg.org/#concept-create-element id=custom-element-conformance:create-an-element data-x-internal=create-an-element>element
  creation</a>, either directly or indirectly, and failing to follow them will result in a custom
  element that cannot be instantiated by the parser or DOM APIs. This is true even if the work is
  done inside a constructor-initiated <a id=custom-element-conformance:microtask href=webappapis.html#microtask>microtask</a>, as a <a href=webappapis.html#perform-a-microtask-checkpoint id=custom-element-conformance:perform-a-microtask-checkpoint>microtask checkpoint</a> can occur immediately after construction.</p>

  <p>When authoring <a href=#concept-custom-element-reaction id=custom-element-conformance:concept-custom-element-reaction>custom element reactions</a>,
  authors should avoid manipulating the node tree as this can lead to unexpected results.</p>

  <div class=example>
   <p>An element's <code>connectedCallback</code> can be queued before the element is
   disconnected, but as the callback queue is still processed, it results in a <code>connectedCallback</code> for an element that is no longer connected:</p>

   <pre><code class='js'><c- a>class</c-> CParent <c- k>extends</c-> HTMLElement <c- p>{</c->
  connectedCallback<c- p>()</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->firstChild<c- p>.</c->remove<c- p>();</c->
  <c- p>}</c->
<c- p>}</c->
customElements<c- p>.</c->define<c- p>(</c-><c- u>&quot;c-parent&quot;</c-><c- p>,</c-> CParent<c- p>);</c->

<c- a>class</c-> CChild <c- k>extends</c-> HTMLElement <c- p>{</c->
  connectedCallback<c- p>()</c-> <c- p>{</c->
    console<c- p>.</c->log<c- p>(</c-><c- u>&quot;CChild connectedCallback: isConnected =&quot;</c-><c- p>,</c-> <c- k>this</c-><c- p>.</c->isConnected<c- p>);</c->
  <c- p>}</c->
<c- p>}</c->
customElements<c- p>.</c->define<c- p>(</c-><c- u>&quot;c-child&quot;</c-><c- p>,</c-> CChild<c- p>);</c->

<c- a>const</c-> parent <c- o>=</c-> <c- k>new</c-> CParent<c- p>(),</c->
      child <c- o>=</c-> <c- k>new</c-> CChild<c- p>();</c->
parent<c- p>.</c->append<c- p>(</c->child<c- p>);</c->
document<c- p>.</c->body<c- p>.</c->append<c- p>(</c->parent<c- p>);</c->

<c- c1>// Logs:</c->
<c- c1>// CChild connectedCallback: isConnected = false</c-></code></pre>
  </div>

  <h5 id=preserving-custom-element-state-when-moved><span class=secno>4.13.2.1</span> Preserving custom element state when moved<a href=#preserving-custom-element-state-when-moved class=self-link></a></h5>

  <p><i>This section is non-normative.</i></p>

  <p>When manipulating the DOM tree, an element can be <a href=https://dom.spec.whatwg.org/#concept-node-move-ext id=preserving-custom-element-state-when-moved:concept-node-move-ext data-x-internal=concept-node-move-ext>moved</a> in the tree while connected. This applies to custom
  elements as well. By default, the "<code>disconnectedCallback</code>" and "<code>connectedCallback</code>" would be called on the element, one after the other. This is
  done to maintain compatibility with existing custom elements that predate the <code id=preserving-custom-element-state-when-moved:dom-parentnode-movebefore><a data-x-internal=dom-parentnode-movebefore href=https://dom.spec.whatwg.org/#dom-parentnode-movebefore>moveBefore()</a></code> method. This means that by default, custom
  elements reset their state as if they were removed and re-inserted. In the example <a href=#custom-elements-autonomous-drawbacks-example>above</a>, the impact would be that the
  observer would be disconnected and re-connected, and the tab index would be reset.</p>

  <p>To opt in to a state-preserving behavior while <a href=https://dom.spec.whatwg.org/#concept-node-move-ext id=preserving-custom-element-state-when-moved:concept-node-move-ext-2 data-x-internal=concept-node-move-ext>moving</a>, the author can implement a "<code>connectedMoveCallback</code>". The existence of this callback, even if empty, would
  supersede the default behavior of calling "<code>disconnectedCallback</code>" and "<code>connectedCallback</code>". "<code>connectedMoveCallback</code>" can also be an
  appropriate place to execute logic that depends on the element's ancestors. For example:</p>

  <pre><code class='js'><c- a>class</c-> TacoButton <c- k>extends</c-> HTMLElement <c- p>{</c->
  <c- k>static</c-> observedAttributes <c- o>=</c-> <c- p>[</c-><c- u>&quot;disabled&quot;</c-><c- p>];</c->

  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->
    <c- k>this</c-><c- p>.</c->_internals <c- o>=</c-> <c- k>this</c-><c- p>.</c->attachInternals<c- p>();</c->
    <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->role <c- o>=</c-> <c- u>&quot;button&quot;</c-><c- p>;</c->

    <c- k>this</c-><c- p>.</c->_observer <c- o>=</c-> <c- k>new</c-> MutationObserver<c- p>(()</c-> <c- p>=&gt;</c-> <c- p>{</c->
      <c- k>this</c-><c- p>.</c->_internals<c- p>.</c->ariaLabel <c- o>=</c-> <c- k>this</c-><c- p>.</c->textContent<c- p>;</c->
    <c- p>});</c->
  <c- p>}</c->

  _notifyMain<c- p>()</c-> <c- p>{</c->
    <c- k>if</c-> <c- p>(</c-><c- k>this</c-><c- p>.</c->parentElement<c- p>.</c->tagName <c- o>===</c-> <c- u>&quot;MAIN&quot;</c-><c- p>)</c-> <c- p>{</c->
      <c- c1>// Execute logic that depends on ancestors.</c->
    <c- p>}</c->
  <c- p>}</c->

  connectedCallback<c- p>()</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->setAttribute<c- p>(</c-><c- u>&quot;tabindex&quot;</c-><c- p>,</c-> <c- u>&quot;0&quot;</c-><c- p>);</c->

    <c- k>this</c-><c- p>.</c->_observer<c- p>.</c->observe<c- p>(</c-><c- k>this</c-><c- p>,</c-> <c- p>{</c->
      childList<c- o>:</c-> <c- kc>true</c-><c- p>,</c->
      characterData<c- o>:</c-> <c- kc>true</c-><c- p>,</c->
      subtree<c- o>:</c-> <c- kc>true</c->
    <c- p>});</c->

    <c- k>this</c-><c- p>.</c->_notifyMain<c- p>();</c->
  <c- p>}</c->

  disconnectedCallback<c- p>()</c-> <c- p>{</c->
    <c- k>this</c-><c- p>.</c->_observer<c- p>.</c->disconnect<c- p>();</c->
  <c- p>}</c->

  <c- c1>// Implementing this function would avoid resetting the tab index or re-registering the</c->
  <c- c1>// mutation observer when this element is moved inside the DOM without being disconnected.</c->
  connectedMoveCallback<c- p>()</c-> <c- p>{</c->
    <c- c1>// The parent can change during a state-preserving move.</c->
    <c- k>this</c-><c- p>.</c->_notifyMain<c- p>();</c->
  <c- p>}</c->
<c- p>}</c-></code></pre>

  <h4 id=custom-elements-core-concepts><span class=secno>4.13.3</span> Core concepts<a href=#custom-elements-core-concepts class=self-link></a></h4>

  <p>A <dfn id=custom-element data-export="">custom element</dfn> is an element that is <a href=https://dom.spec.whatwg.org/#concept-element-custom id=custom-elements-core-concepts:concept-element-custom data-x-internal=concept-element-custom>custom</a>. Informally, this means that its constructor and
  prototype are defined by the author, instead of by the user agent. This author-supplied
  constructor function is called the <dfn id=custom-element-constructor data-export="">custom element constructor</dfn>.</p>

  <p>Two distinct types of <a href=#custom-element id=custom-elements-core-concepts:custom-element>custom elements</a> can be defined:</p>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is title="The is global attribute allows you to specify that a standard HTML element should behave like a defined custom built-in element (see Using custom elements for more details).">Global_attributes/is</a><div class=support><span class="firefox yes"><span>Firefox</span><span>63+</span></span><span class="safari no"><span>Safari</span><span>No</span></span><span class="chrome yes"><span>Chrome</span><span>67+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><ul><li><p>An <dfn id=autonomous-custom-element data-export="">autonomous custom element</dfn>, which is defined with no <code id=custom-elements-core-concepts:dom-elementdefinitionoptions-extends><a href=#dom-elementdefinitionoptions-extends>extends</a></code> option. These types of custom
   elements have a local name equal to their <a href=#concept-custom-element-definition-name id=custom-elements-core-concepts:concept-custom-element-definition-name>defined name</a>.<li><p>A <dfn id=customized-built-in-element data-export="">customized built-in element</dfn>, which is defined with an <code id=custom-elements-core-concepts:dom-elementdefinitionoptions-extends-2><a href=#dom-elementdefinitionoptions-extends>extends</a></code> option. These types of custom
   elements have a local name equal to the value passed in their <code id=custom-elements-core-concepts:dom-elementdefinitionoptions-extends-3><a href=#dom-elementdefinitionoptions-extends>extends</a></code> option, and their <a href=#concept-custom-element-definition-name id=custom-elements-core-concepts:concept-custom-element-definition-name-2>defined name</a> is used as the value of the
   <dfn data-dfn-for=html-global id=attr-is data-dfn-type=element-attr><code>is</code></dfn> attribute, which
   therefore must be a <a href=#valid-custom-element-name id=custom-elements-core-concepts:valid-custom-element-name>valid custom element name</a>.</ul>

  <p>After a <a href=#custom-element id=custom-elements-core-concepts:custom-element-2>custom element</a> is <a href=https://dom.spec.whatwg.org/#concept-create-element id=custom-elements-core-concepts:create-an-element data-x-internal=create-an-element>created</a>,
  changing the value of the <code id=custom-elements-core-concepts:attr-is><a href=#attr-is>is</a></code> attribute does not
  change the element's behavior, as it is saved on the element as its <a href=https://dom.spec.whatwg.org/#concept-element-is-value id=custom-elements-core-concepts:concept-element-is-value data-x-internal=concept-element-is-value><code>is</code> value</a>.</p>

  <p><a href=#autonomous-custom-element id=custom-elements-core-concepts:autonomous-custom-element>Autonomous custom elements</a> have the following
  element definition:</p>

  <dl class=element><dt><a href=dom.html#concept-element-categories id=custom-elements-core-concepts:concept-element-categories>Categories</a>:<dd><a id=custom-elements-core-concepts:flow-content-2 href=dom.html#flow-content-2>Flow content</a>.<dd><a id=custom-elements-core-concepts:phrasing-content-2 href=dom.html#phrasing-content-2>Phrasing content</a>.<dd><a id=custom-elements-core-concepts:palpable-content-2 href=dom.html#palpable-content-2>Palpable content</a>.<dd>For <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element>form-associated custom elements</a>: <a href=forms.html#category-listed id=custom-elements-core-concepts:category-listed>Listed</a>, <a href=forms.html#category-label id=custom-elements-core-concepts:category-label>labelable</a>, <a href=forms.html#category-submit id=custom-elements-core-concepts:category-submit>submittable</a>, and <a href=forms.html#category-reset id=custom-elements-core-concepts:category-reset>resettable</a> <a id=custom-elements-core-concepts:form-associated-element href=forms.html#form-associated-element>form-associated element</a>.<dt><a href=dom.html#concept-element-contexts id=custom-elements-core-concepts:concept-element-contexts>Contexts in which this element can be used</a>:<dd>Where <a id=custom-elements-core-concepts:phrasing-content-2-2 href=dom.html#phrasing-content-2>phrasing content</a> is expected.<dt><a href=dom.html#concept-element-content-model id=custom-elements-core-concepts:concept-element-content-model>Content model</a>:<dd><a id=custom-elements-core-concepts:transparent href=dom.html#transparent>Transparent</a>.<dt><a href=dom.html#concept-element-attributes id=custom-elements-core-concepts:concept-element-attributes>Content attributes</a>:<dd><a id=custom-elements-core-concepts:global-attributes href=dom.html#global-attributes>Global attributes</a>, except the <code id=custom-elements-core-concepts:attr-is-2><a href=#attr-is>is</a></code> attribute<dd><code id=custom-elements-core-concepts:attr-fae-form><a href=form-control-infrastructure.html#attr-fae-form>form</a></code>, for <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-2>form-associated custom elements</a> —  Associates the element with a <code id=custom-elements-core-concepts:the-form-element><a href=forms.html#the-form-element>form</a></code> element
     <dd><code id=custom-elements-core-concepts:attr-fe-disabled><a href=form-control-infrastructure.html#attr-fe-disabled>disabled</a></code>, for <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-3>form-associated custom elements</a> —  Whether the form control is disabled
     <dd><code id=custom-elements-core-concepts:attr-face-readonly><a href=#attr-face-readonly>readonly</a></code>, for <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-4>form-associated custom elements</a> —  Affects <code id=custom-elements-core-concepts:dom-elementinternals-willvalidate><a href=form-control-infrastructure.html#dom-elementinternals-willvalidate>willValidate</a></code>, plus any behavior added by the custom element author
     <dd><code id=custom-elements-core-concepts:attr-fe-name><a href=form-control-infrastructure.html#attr-fe-name>name</a></code>, for <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-5>form-associated custom elements</a> —  Name of the element to use for <a id=custom-elements-core-concepts:form-submission-2 href=form-control-infrastructure.html#form-submission-2>form submission</a> and in the <code id=custom-elements-core-concepts:dom-form-elements><a href=forms.html#dom-form-elements>form.elements</a></code> API 
     <dd>Any other attribute that has no namespace (see prose).<dt><a href=dom.html#concept-element-accessibility-considerations id=custom-elements-core-concepts:concept-element-accessibility-considerations>Accessibility considerations</a>:<dd>For <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-6>form-associated custom elements</a>: <a href=https://w3c.github.io/html-aria/#el-form-associated-custom-element>for authors</a>; <a href=https://w3c.github.io/html-aam/#el-form-associated-custom-element>for implementers</a>.<dd>Otherwise: <a href=https://w3c.github.io/html-aria/#el-autonomous-custom-element>for authors</a>; <a href=https://w3c.github.io/html-aam/#el-autonomous-custom-element>for implementers</a>.<dt><a href=dom.html#concept-element-dom id=custom-elements-core-concepts:concept-element-dom>DOM interface</a>:<dd>Supplied by the element's author (inherits from <code id=custom-elements-core-concepts:htmlelement><a href=dom.html#htmlelement>HTMLElement</a></code>)</dl>


  <p>An <a href=#autonomous-custom-element id=custom-elements-core-concepts:autonomous-custom-element-2>autonomous custom element</a> does not have any special meaning: it
  <a id=custom-elements-core-concepts:represents href=dom.html#represents>represents</a> its children. A <a href=#customized-built-in-element id=custom-elements-core-concepts:customized-built-in-element>customized built-in element</a> inherits the
  semantics of the element that it extends.</p>

  <p>Any namespace-less attribute that is relevant to the element's functioning, as determined by
  the element's author, may be specified on an <a href=#autonomous-custom-element id=custom-elements-core-concepts:autonomous-custom-element-3>autonomous custom element</a>, so long as
  the attribute name is a <a id=custom-elements-core-concepts:valid-attribute-local-name href=https://dom.spec.whatwg.org/#valid-attribute-local-name data-x-internal=valid-attribute-local-name>valid attribute local name</a> and contains no <a href=https://infra.spec.whatwg.org/#ascii-upper-alpha id=custom-elements-core-concepts:uppercase-ascii-letters data-x-internal=uppercase-ascii-letters>ASCII upper alphas</a>. The exception is the <code id=custom-elements-core-concepts:attr-is-3><a href=#attr-is>is</a></code> attribute, which must not be specified on an <a href=#autonomous-custom-element id=custom-elements-core-concepts:autonomous-custom-element-4>autonomous custom
  element</a> (and which will have no effect if it is).</p>

  <p><a href=#customized-built-in-element id=custom-elements-core-concepts:customized-built-in-element-2>Customized built-in elements</a> follow the
  normal requirements for attributes, based on the elements they extend. To add custom
  attribute-based behavior, use <code id=custom-elements-core-concepts:attr-data-*><a href=dom.html#attr-data-*>data-*</a></code> attributes.</p>

  <hr>

  <p>An <a href=#autonomous-custom-element id=custom-elements-core-concepts:autonomous-custom-element-5>autonomous custom element</a> is called a <dfn id=form-associated-custom-element data-export="">form-associated custom
  element</dfn> if the element is associated with a <a href=#custom-element-definition id=custom-elements-core-concepts:custom-element-definition>custom element definition</a> whose
  <a href=#concept-custom-element-definition-form-associated id=custom-elements-core-concepts:concept-custom-element-definition-form-associated>form-associated</a> field is
  set to true.</p>

  <p>The <code id=custom-elements-core-concepts:attr-fe-name-2><a href=form-control-infrastructure.html#attr-fe-name>name</a></code> attribute represents the <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-7>form-associated
  custom element</a>'s name. The <code id=custom-elements-core-concepts:attr-fe-disabled-2><a href=form-control-infrastructure.html#attr-fe-disabled>disabled</a></code> attribute is
  used to make the <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-8>form-associated custom element</a> non-interactive and to prevent its
  <a href=#face-submission-value id=custom-elements-core-concepts:face-submission-value>submission value</a> from being submitted. The <code id=custom-elements-core-concepts:attr-fae-form-2><a href=form-control-infrastructure.html#attr-fae-form>form</a></code> attribute is used to explicitly associate the
  <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-9>form-associated custom element</a> with its <a id=custom-elements-core-concepts:form-owner href=form-control-infrastructure.html#form-owner>form owner</a>.</p>

  <p>The <dfn data-dfn-for="form-associated custom elements" id=attr-face-readonly data-dfn-type=element-attr><code>readonly</code></dfn> attribute of <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-10>form-associated custom elements</a> specifies that the element is <a id=custom-elements-core-concepts:barred-from-constraint-validation href=form-control-infrastructure.html#barred-from-constraint-validation>barred
  from constraint validation</a>. User agents don't provide any other behavior for the attribute,
  but custom element authors should, where possible, use its presence to make their control
  non-editable in some appropriate fashion, similar to the behavior for the <a href=input.html#attr-input-readonly id=custom-elements-core-concepts:attr-input-readonly>readonly</a> attribute on built-in form controls.</p>

  <p><strong>Constraint validation</strong>: If the <code id=custom-elements-core-concepts:attr-face-readonly-2><a href=#attr-face-readonly>readonly</a></code> attribute is specified on a <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-11>form-associated
  custom element</a>, the element is <a id=custom-elements-core-concepts:barred-from-constraint-validation-2 href=form-control-infrastructure.html#barred-from-constraint-validation>barred from constraint validation</a>.</p>

  <p>The <a href=form-control-infrastructure.html#concept-form-reset-control id=custom-elements-core-concepts:concept-form-reset-control>reset algorithm</a> for <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-12>form-associated custom elements</a> is to <a href=#enqueue-a-custom-element-callback-reaction id=custom-elements-core-concepts:enqueue-a-custom-element-callback-reaction>enqueue
  a custom element callback reaction</a> with the element, callback name "<code>formResetCallback</code>", and « ».</p>

  <hr>

  <p>A string <var>name</var> is a <dfn id=valid-custom-element-name data-export="">valid custom element name</dfn> if all of the
  following are true:</p>

  <ul><li>
    <p><var>name</var> is a <a id=custom-elements-core-concepts:valid-element-local-name href=https://dom.spec.whatwg.org/#valid-element-local-name data-x-internal=valid-element-local-name>valid element local name</a>;</p>

    <p class=note>This ensures the custom element can be created with <code id=custom-elements-core-concepts:dom-document-createelement><a data-x-internal=dom-document-createelement href=https://dom.spec.whatwg.org/#dom-document-createelement>createElement()</a></code>.</p>
   <li>
    <p><var>name</var>'s 0th <a id=custom-elements-core-concepts:code-point href=https://infra.spec.whatwg.org/#code-point data-x-internal=code-point>code point</a> is an <a id=custom-elements-core-concepts:lowercase-ascii-letters href=https://infra.spec.whatwg.org/#ascii-lower-alpha data-x-internal=lowercase-ascii-letters>ASCII lower alpha</a>;</p>

    <p class=note>This ensures the HTML parser will treat the name as a tag name instead of as
    text.</p>
   <li>
    <p><var>name</var> does not contain any <a href=https://infra.spec.whatwg.org/#ascii-upper-alpha id=custom-elements-core-concepts:uppercase-ascii-letters-2 data-x-internal=uppercase-ascii-letters>ASCII upper
    alphas</a>;</p>

    <p class=note>This ensures the user agent can always treat HTML elements
    ASCII-case-insensitively.</p>
   <li>
    <p><var>name</var> contains a U+002D (-); and</p>

    <p class=note>This is used for namespacing and to ensure forward compatibility (since no
    elements will be added to HTML, SVG, or MathML with hyphen-containing local names going
    forward).</p>
   <li>
    <p><var>name</var> is not one of the following:</p>

    <ul class=brief><li>"<code>annotation-xml</code>"<li>"<code>color-profile</code>"<li>"<code>font-face</code>"<li>"<code>font-face-src</code>"<li>"<code>font-face-uri</code>"<li>"<code>font-face-format</code>"<li>"<code>font-face-name</code>"<li>"<code>missing-glyph</code>"</ul>

    <p class=note>The list of names above is the summary of all hyphen-containing element names
    from the <a href=infrastructure.html#other-applicable-specifications id=custom-elements-core-concepts:other-applicable-specifications>applicable specifications</a>, namely
    <cite>SVG 2</cite> and <cite>MathML</cite>. <a href=references.html#refsSVG>[SVG]</a> <a href=references.html#refsMATHML>[MATHML]</a></p>
   </ul>

  <p>Apart from these restrictions, a large variety of names is allowed, to give maximum
  flexibility for use cases like <code>&lt;math-α></code> or <code>&lt;emotion-😍></code>.</p>

  

  <hr>

  <p>A <dfn id=custom-element-definition data-export="">custom element definition</dfn> describes a <a href=#custom-element id=custom-elements-core-concepts:custom-element-3>custom element</a> and
  consists of:</p>

  <dl><dt>A <dfn data-dfn-for="custom element definition" id=concept-custom-element-definition-name data-export="">name</dfn><dd>A <a href=#valid-custom-element-name id=custom-elements-core-concepts:valid-custom-element-name-2>valid custom element name</a><dt>A <dfn data-dfn-for="custom element definition" id=concept-custom-element-definition-local-name data-export="">local name</dfn><dd>A local name<dt>A <dfn data-dfn-for="custom element definition" id=concept-custom-element-definition-constructor data-export="">constructor</dfn><dd>A Web IDL <code id=custom-elements-core-concepts:customelementconstructor><a href=#customelementconstructor>CustomElementConstructor</a></code> callback function type value wrapping
   the <a href=#custom-element-constructor id=custom-elements-core-concepts:custom-element-constructor>custom element constructor</a><dt>A list of <dfn id=concept-custom-element-definition-observed-attributes>observed
   attributes</dfn><dd>A <code>sequence&lt;DOMString></code><dt>A collection of <dfn id=concept-custom-element-definition-lifecycle-callbacks>lifecycle callbacks</dfn><dd>A map, whose keys are the strings "<code>connectedCallback</code>", "<code>disconnectedCallback</code>", "<code>adoptedCallback</code>", "<code>connectedMoveCallback</code>", "<code>attributeChangedCallback</code>",
   "<code>formAssociatedCallback</code>", "<code>formDisabledCallback</code>",
   "<code>formResetCallback</code>", and "<code>formStateRestoreCallback</code>". The corresponding values are either a Web IDL <code id=custom-elements-core-concepts:idl-function><a data-x-internal=idl-function href=https://webidl.spec.whatwg.org/#common-Function>Function</a></code> callback function type value, or null. By default the value
   of each entry is null.<dt>A <dfn id=concept-custom-element-definition-construction-stack>construction
   stack</dfn><dd>A list, initially empty, that is manipulated by the <a href=#concept-upgrade-an-element id=custom-elements-core-concepts:concept-upgrade-an-element>upgrade an element</a> algorithm and the <a href=dom.html#html-element-constructors>HTML element constructors</a>. Each entry in the list will be
   either an element or an <dfn id=concept-already-constructed-marker><i>already
   constructed</i> marker</dfn>.<dt>A <dfn id=concept-custom-element-definition-form-associated>form-associated</dfn>
   boolean<dd>If this is true, user agent treats elements associated to this
   <a href=#custom-element-definition id=custom-elements-core-concepts:custom-element-definition-2>custom element definition</a> as <a href=#form-associated-custom-element id=custom-elements-core-concepts:form-associated-custom-element-13>form-associated custom elements</a>.<dt>A <dfn id=concept-custom-element-definition-disable-internals>disable
   internals</dfn> boolean<dd>Controls <code id=custom-elements-core-concepts:dom-attachinternals><a href=#dom-attachinternals>attachInternals()</a></code>.

   <dt>A <dfn data-dfn-for="custom element definition" id=concept-custom-element-definition-disable-shadow data-export="">disable shadow</dfn> boolean<dd>Controls <code id=custom-elements-core-concepts:dom-element-attachshadow><a data-x-internal=dom-element-attachshadow href=https://dom.spec.whatwg.org/#dom-element-attachshadow>attachShadow()</a></code>.
  </dl>

  <p>To <dfn id=look-up-a-custom-element-definition data-export="">look up a custom element definition</dfn>, given null or a
  <code id=custom-elements-core-concepts:customelementregistry><a href=#customelementregistry>CustomElementRegistry</a></code> object <var>registry</var>, string-or-null
  <var>namespace</var>, string <var>localName</var>, and string-or-null <var>is</var>, perform the
  following steps. They will return either a <a href=#custom-element-definition id=custom-elements-core-concepts:custom-element-definition-3>custom element definition</a> or null:</p>

  <ol><li><p>If <var>registry</var> is null, then return null.<li><p>If <var>namespace</var> is not the <a id=custom-elements-core-concepts:html-namespace-2 href=https://infra.spec.whatwg.org/#html-namespace data-x-internal=html-namespace-2>HTML namespace</a>, then return null.<li><p>If <var>registry</var>'s <a href=#custom-element-definition-set id=custom-elements-core-concepts:custom-element-definition-set>custom element definition set</a> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-core-concepts:list-contains data-x-internal=list-contains>contains</a> an item with <a href=#concept-custom-element-definition-name id=custom-elements-core-concepts:concept-custom-element-definition-name-3>name</a> and <a href=#concept-custom-element-definition-local-name id=custom-elements-core-concepts:concept-custom-element-definition-local-name>local name</a> both equal to
   <var>localName</var>, then return that item.<li><p>If <var>registry</var>'s <a href=#custom-element-definition-set id=custom-elements-core-concepts:custom-element-definition-set-2>custom element definition set</a> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-core-concepts:list-contains-2 data-x-internal=list-contains>contains</a> an item with <a href=#concept-custom-element-definition-name id=custom-elements-core-concepts:concept-custom-element-definition-name-4>name</a> equal to <var>is</var> and <a href=#concept-custom-element-definition-local-name id=custom-elements-core-concepts:concept-custom-element-definition-local-name-2>local name</a> equal to
   <var>localName</var>, then return that item.<li><p>Return null.</ol>

  

  <h4 id=custom-elements-api><span class=secno>4.13.4</span> The <code id=custom-elements-api:customelementregistry><a href=#customelementregistry>CustomElementRegistry</a></code> interface<a href=#custom-elements-api class=self-link></a></h4><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry title="The CustomElementRegistry interface provides methods for registering custom elements and querying registered elements. To get an instance of it, use the window.customElements property.">CustomElementRegistry</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>63+</span></span><span class="safari yes"><span>Safari</span><span>10.1+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  

  <p>Each <a id=custom-elements-api:similar-origin-window-agent href=webappapis.html#similar-origin-window-agent>similar-origin window agent</a> has an associated <dfn data-dfn-for="similar-origin
  window agent" id=active-custom-element-constructor-map data-export="">active custom element constructor map</dfn>, which is a <a href=https://infra.spec.whatwg.org/#ordered-map id=custom-elements-api:ordered-map data-x-internal=ordered-map>map</a> of constructors to <code id=custom-elements-api:customelementregistry-2><a href=#customelementregistry>CustomElementRegistry</a></code> objects.</p>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/Window/customElements title="The customElements read-only property of the Window interface returns a reference to the CustomElementRegistry object, which can be used to register new custom elements and get information about previously registered custom elements.">Window/customElements</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>63+</span></span><span class="safari yes"><span>Safari</span><span>10.1+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <code id=custom-elements-api:window><a href=nav-history-apis.html#window>Window</a></code> <dfn data-dfn-for=Window id=dom-window-customelements data-dfn-type=attribute><code>customElements</code></dfn> getter steps are:</p>

  <ol><li>
    <p><a id=custom-elements-api:assert href=https://infra.spec.whatwg.org/#assert data-x-internal=assert>Assert</a>: <a id=custom-elements-api:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=nav-history-apis.html#concept-document-window id=custom-elements-api:concept-document-window>associated
    <code>Document</code></a>'s <a href=https://dom.spec.whatwg.org/#document-custom-element-registry id=custom-elements-api:document-custom-element-registry data-x-internal=document-custom-element-registry>custom element
    registry</a> is a <code id=custom-elements-api:customelementregistry-3><a href=#customelementregistry>CustomElementRegistry</a></code> object.</p>

    <p class=note>A <code id=custom-elements-api:window-2><a href=nav-history-apis.html#window>Window</a></code>'s <a href=nav-history-apis.html#concept-document-window id=custom-elements-api:concept-document-window-2>associated
    <code>Document</code></a> is always created with a new
    <code id=custom-elements-api:customelementregistry-4><a href=#customelementregistry>CustomElementRegistry</a></code> object.</p>
   <li><p>Return <a id=custom-elements-api:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=nav-history-apis.html#concept-document-window id=custom-elements-api:concept-document-window-3>associated
   <code>Document</code></a>'s <a href=https://dom.spec.whatwg.org/#document-custom-element-registry id=custom-elements-api:document-custom-element-registry-2 data-x-internal=document-custom-element-registry>custom element
   registry</a>.</ol>

  <pre><code class='idl'>[<c- g>Exposed</c->=<c- n>Window</c->]
<c- b>interface</c-> <dfn id='customelementregistry' data-dfn-type='interface'><c- g>CustomElementRegistry</c-></dfn> {
  <a href='#dom-customelementregistry' id='custom-elements-api:dom-customelementregistry'><c- g>constructor</c-></a>();

  [<a href='#cereactions' id='custom-elements-api:cereactions'><c- g>CEReactions</c-></a>] <c- b>undefined</c-> <a href='#dom-customelementregistry-define' id='custom-elements-api:dom-customelementregistry-define'><c- g>define</c-></a>(<c- b>DOMString</c-> <var><c- g>name</c-></var>, <a href='#customelementconstructor' id='custom-elements-api:customelementconstructor'><c- n>CustomElementConstructor</c-></a> <var><c- g>constructor</c-></var>, <c- b>optional</c-> <a href='#elementdefinitionoptions' id='custom-elements-api:elementdefinitionoptions'><c- n>ElementDefinitionOptions</c-></a> <var><c- g>options</c-></var> = {});
  (<a href='#customelementconstructor' id='custom-elements-api:customelementconstructor-2'><c- n>CustomElementConstructor</c-></a> <c- b>or</c-> <c- b>undefined</c->) <a href='#dom-customelementregistry-get' id='custom-elements-api:dom-customelementregistry-get'><c- g>get</c-></a>(<c- b>DOMString</c-> <var><c- g>name</c-></var>);
  <c- b>DOMString</c->? <a href='#dom-customelementregistry-getname' id='custom-elements-api:dom-customelementregistry-getname'><c- g>getName</c-></a>(<c- n>CustomElementConstructor</c-> <var><c- g>constructor</c-></var>);
  <a href='https://webidl.spec.whatwg.org/#idl-promise' id='custom-elements-api:idl-promise' data-x-internal='idl-promise'><c- b>Promise</c-></a>&lt;<a href='#customelementconstructor' id='custom-elements-api:customelementconstructor-3'><c- n>CustomElementConstructor</c-></a>&gt; <a href='#dom-customelementregistry-whendefined' id='custom-elements-api:dom-customelementregistry-whendefined'><c- g>whenDefined</c-></a>(<c- b>DOMString</c-> <var><c- g>name</c-></var>);
  [<a href='#cereactions' id='custom-elements-api:cereactions-2'><c- g>CEReactions</c-></a>] <c- b>undefined</c-> <a href='#dom-customelementregistry-upgrade' id='custom-elements-api:dom-customelementregistry-upgrade'><c- g>upgrade</c-></a>(<a id='custom-elements-api:node' href='https://dom.spec.whatwg.org/#interface-node' data-x-internal='node'><c- n>Node</c-></a> <var><c- g>root</c-></var>);
  <c- b>undefined</c-> <a href='#dom-customelementregistry-initialize' id='custom-elements-api:dom-customelementregistry-initialize'><c- g>initialize</c-></a>(<a id='custom-elements-api:node-2' href='https://dom.spec.whatwg.org/#interface-node' data-x-internal='node'><c- n>Node</c-></a> <var><c- g>root</c-></var>);
};

<c- b>callback</c-> <dfn id='customelementconstructor' data-dfn-type='callback'><c- g>CustomElementConstructor</c-></dfn> = <a id='custom-elements-api:htmlelement' href='dom.html#htmlelement'><c- n>HTMLElement</c-></a> ();

<c- b>dictionary</c-> <dfn id='elementdefinitionoptions' data-dfn-type='dictionary'><c- g>ElementDefinitionOptions</c-></dfn> {
  <c- b>DOMString</c-> <dfn data-dfn-for='ElementDefinitionOptions' id='dom-elementdefinitionoptions-extends' data-dfn-type='dict-member'><c- g>extends</c-></dfn>;
};</code></pre>

  <p>Every <code id=custom-elements-api:customelementregistry-5><a href=#customelementregistry>CustomElementRegistry</a></code> has an <dfn data-dfn-for=CustomElementRegistry id=is-scoped data-export="">is
  scoped</dfn>, a boolean, initially false.</p>

  <p>Every <code id=custom-elements-api:customelementregistry-6><a href=#customelementregistry>CustomElementRegistry</a></code> has a <dfn data-dfn-for=CustomElementRegistry id=scoped-document-set data-export="">scoped
  document set</dfn>, a <a id=custom-elements-api:set href=https://infra.spec.whatwg.org/#ordered-set data-x-internal=set>set</a> of <code id=custom-elements-api:document><a href=dom.html#document>Document</a></code> objects, initially « ».</p>

  <p>Every <code id=custom-elements-api:customelementregistry-7><a href=#customelementregistry>CustomElementRegistry</a></code> has a <dfn id=custom-element-definition-set>custom element definition set</dfn>, a
  <a id=custom-elements-api:set-2 href=https://infra.spec.whatwg.org/#ordered-set data-x-internal=set>set</a> of <a href=#custom-element-definition id=custom-elements-api:custom-element-definition>custom element definitions</a>,
  initially « ». Lookup of items in this <a id=custom-elements-api:set-3 href=https://infra.spec.whatwg.org/#ordered-set data-x-internal=set>set</a> uses their <a href=#concept-custom-element-definition-name id=custom-elements-api:concept-custom-element-definition-name>name</a>, <a href=#concept-custom-element-definition-local-name id=custom-elements-api:concept-custom-element-definition-local-name>local name</a>, or <a href=#concept-custom-element-definition-constructor id=custom-elements-api:concept-custom-element-definition-constructor>constructor</a>.</p>

  <p>Every <code id=custom-elements-api:customelementregistry-8><a href=#customelementregistry>CustomElementRegistry</a></code> also has an <dfn id=element-definition-is-running>element definition is running</dfn>
  boolean which is used to prevent reentrant invocations of <a href=#element-definition id=custom-elements-api:element-definition>element definition</a>. It is
  initially false.</p>

  <p>Every <code id=custom-elements-api:customelementregistry-9><a href=#customelementregistry>CustomElementRegistry</a></code> also has a <dfn id=when-defined-promise-map>when-defined promise map</dfn>, a
  <a href=https://infra.spec.whatwg.org/#ordered-map id=custom-elements-api:ordered-map-2 data-x-internal=ordered-map>map</a> of <a href=#valid-custom-element-name id=custom-elements-api:valid-custom-element-name>valid custom
  element names</a> to promises. It is used to implement the <code id=custom-elements-api:dom-customelementregistry-whendefined-2><a href=#dom-customelementregistry-whendefined>whenDefined()</a></code> method.</p>

  <p>To <dfn id=look-up-a-custom-element-registry data-export="">look up a custom element registry</dfn>, given a <code id=custom-elements-api:node-3><a data-x-internal=node href=https://dom.spec.whatwg.org/#interface-node>Node</a></code> object
  <var>node</var>:</p>

  <ol><li><p>If <var>node</var> is an <code id=custom-elements-api:element><a data-x-internal=element href=https://dom.spec.whatwg.org/#interface-element>Element</a></code> object, then return <var>node</var>'s <a href=https://dom.spec.whatwg.org/#element-custom-element-registry id=custom-elements-api:element-custom-element-registry data-x-internal=element-custom-element-registry>custom element registry</a>.<li><p>If <var>node</var> is a <code id=custom-elements-api:shadowroot><a data-x-internal=shadowroot href=https://dom.spec.whatwg.org/#interface-shadowroot>ShadowRoot</a></code> object, then return <var>node</var>'s
   <a href=https://dom.spec.whatwg.org/#shadowroot-custom-element-registry id=custom-elements-api:shadow-root-custom-element-registry data-x-internal=shadow-root-custom-element-registry>custom element registry</a>.<li><p>If <var>node</var> is a <code id=custom-elements-api:document-2><a href=dom.html#document>Document</a></code> object, then return <var>node</var>'s <a href=https://dom.spec.whatwg.org/#document-custom-element-registry id=custom-elements-api:document-custom-element-registry-3 data-x-internal=document-custom-element-registry>custom element registry</a>.<li><p>Return null.</ol>

  

  <dl class=domintro><dt><code><var>registry</var> = <var>window</var>.<a href=#dom-window-customelements id=dom-window-customelements-dev>customElements</a></code><dd>Returns the global's associated <code id=custom-elements-api:document-3><a href=dom.html#document>Document</a></code>'s <code id=custom-elements-api:customelementregistry-10><a href=#customelementregistry>CustomElementRegistry</a></code>
   object.<dt><code><var>registry</var> = new <a href=#dom-customelementregistry id=dom-customelementregistry-dev>CustomElementRegistry</a>()</code><dd>Constructs a new <code id=custom-elements-api:customelementregistry-11><a href=#customelementregistry>CustomElementRegistry</a></code> object, for scoped usage.<dt><code><var>registry</var>.<a href=#dom-customelementregistry-define id=dom-customelementregistry-define-dev>define</a>(<var>name</var>,
   <var>constructor</var>)</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define title="The define() method of the CustomElementRegistry interface defines a new custom element.">CustomElementRegistry/define</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>63+</span></span><span class="safari yes"><span>Safari</span><span>10.1+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd>Defines a new <a href=#custom-element id=custom-elements-api:custom-element>custom element</a>, mapping the given name to the given constructor
   as an <a href=#autonomous-custom-element id=custom-elements-api:autonomous-custom-element>autonomous custom element</a>.<dt><code><var>registry</var>.<a href=#dom-customelementregistry-define id=custom-elements-api:dom-customelementregistry-define-2>define</a>(<var>name</var>, <var>constructor</var>,
   { extends: <var>baseLocalName</var> })</code><dd>Defines a new <a href=#custom-element id=custom-elements-api:custom-element-2>custom element</a>, mapping the given name to the given constructor as
   a <a href=#customized-built-in-element id=custom-elements-api:customized-built-in-element>customized built-in element</a> for the <a id=custom-elements-api:element-type href=infrastructure.html#element-type>element type</a> identified by the
   supplied <var>baseLocalName</var>. A <a id=custom-elements-api:notsupportederror href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a>
   <code id=custom-elements-api:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> will be thrown upon trying to extend a <a href=#custom-element id=custom-elements-api:custom-element-3>custom element</a> or
   an unknown element, or when <var>registry</var> is not a global
   <code id=custom-elements-api:customelementregistry-12><a href=#customelementregistry>CustomElementRegistry</a></code> object.<dt><code><var>registry</var>.<a href=#dom-customelementregistry-get id=dom-customelementregistry-get-dev>get</a>(<var>name</var>)</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/get title="The get() method of the CustomElementRegistry interface returns the constructor for a previously-defined custom element.">CustomElementRegistry/get</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>63+</span></span><span class="safari yes"><span>Safari</span><span>10.1+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd>Retrieves the <a href=#custom-element-constructor id=custom-elements-api:custom-element-constructor>custom element constructor</a> defined for the given <a href=#concept-custom-element-definition-name id=custom-elements-api:concept-custom-element-definition-name-2>name</a>. Returns undefined if there is no
   <a href=#custom-element-definition id=custom-elements-api:custom-element-definition-2>custom element definition</a> with the given <a href=#concept-custom-element-definition-name id=custom-elements-api:concept-custom-element-definition-name-3>name</a>.<dt><code><var>registry</var>.<a href=#dom-customelementregistry-getname id=dom-customelementregistry-getname-dev>getName</a>(<var>constructor</var>)</code><dd>Retrieves the given name for a <a href=#custom-element id=custom-elements-api:custom-element-4>custom element</a> defined for the given <a href=#concept-custom-element-definition-constructor id=custom-elements-api:concept-custom-element-definition-constructor-2>constructor</a>. Returns null if there is no
   <a href=#custom-element-definition id=custom-elements-api:custom-element-definition-3>custom element definition</a> with the given <a href=#concept-custom-element-definition-constructor id=custom-elements-api:concept-custom-element-definition-constructor-3>constructor</a>.<dt><code><var>registry</var>.<a href=#dom-customelementregistry-whendefined id=dom-customelementregistry-whendefined-dev>whenDefined</a>(<var>name</var>)</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/whenDefined title="The whenDefined() method of the CustomElementRegistry interface returns a Promise that resolves when the named element is defined.">CustomElementRegistry/whenDefined</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>63+</span></span><span class="safari yes"><span>Safari</span><span>10.1+</span></span><span class="chrome yes"><span>Chrome</span><span>54+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd>Returns a promise that will be fulfilled with the <a href=#custom-element id=custom-elements-api:custom-element-5>custom element</a>'s constructor
   when a <a href=#custom-element id=custom-elements-api:custom-element-6>custom element</a> becomes defined with the given name. (If such a <a href=#custom-element id=custom-elements-api:custom-element-7>custom
   element</a> is already defined, the returned promise will be immediately fulfilled.) Returns a
   promise rejected with a <a id=custom-elements-api:syntaxerror href=https://webidl.spec.whatwg.org/#syntaxerror data-x-internal=syntaxerror>"<code>SyntaxError</code>"</a> <code id=custom-elements-api:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> if not
   given a <a href=#valid-custom-element-name id=custom-elements-api:valid-custom-element-name-2>valid custom element name</a>.<dt><code><var>registry</var>.<a href=#dom-customelementregistry-upgrade id=dom-customelementregistry-upgrade-dev>upgrade</a>(<var>root</var>)</code><div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/upgrade title="The upgrade() method of the CustomElementRegistry interface upgrades all shadow-containing custom elements in a Node subtree, even before they are connected to the main document.">CustomElementRegistry/upgrade</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>63+</span></span><span class="safari yes"><span>Safari</span><span>12.1+</span></span><span class="chrome yes"><span>Chrome</span><span>68+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><dd><a href=#concept-try-upgrade id=custom-elements-api:concept-try-upgrade>Tries to upgrade</a> all <a id=custom-elements-api:shadow-including-inclusive-descendant href=https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant data-x-internal=shadow-including-inclusive-descendant>shadow-including
   inclusive descendant</a> elements of <var>root</var>, even if they are not
   <a id=custom-elements-api:connected href=https://dom.spec.whatwg.org/#connected data-x-internal=connected>connected</a>.<dt><code><var>registry</var>.<a href=#dom-customelementregistry-initialize id=dom-customelementregistry-initialize-dev>initialize</a>(<var>root</var>)</code><dd>Each <a id=custom-elements-api:inclusive-descendant href=https://dom.spec.whatwg.org/#concept-tree-inclusive-descendant data-x-internal=inclusive-descendant>inclusive descendant</a> of <var>root</var> with a null registry will have it
   updated to this <code id=custom-elements-api:customelementregistry-13><a href=#customelementregistry>CustomElementRegistry</a></code> object. A
   <a id=custom-elements-api:notsupportederror-2 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=custom-elements-api:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code> will be thrown if this
   <code id=custom-elements-api:customelementregistry-14><a href=#customelementregistry>CustomElementRegistry</a></code> object is not for scoped usage and either <var>root</var> is a
   <code id=custom-elements-api:document-4><a href=dom.html#document>Document</a></code> node or <var>root</var>'s <a id=custom-elements-api:node-document href=https://dom.spec.whatwg.org/#concept-node-document data-x-internal=node-document>node document</a>'s <a href=https://dom.spec.whatwg.org/#document-custom-element-registry id=custom-elements-api:document-custom-element-registry-4 data-x-internal=document-custom-element-registry>custom element registry</a> is not this
   <code id=custom-elements-api:customelementregistry-15><a href=#customelementregistry>CustomElementRegistry</a></code> object.</dl>

  <p>The <dfn id=dom-customelementregistry><code>new CustomElementRegistry()</code></dfn> constructor
  steps are to set <a id=custom-elements-api:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#is-scoped id=custom-elements-api:is-scoped>is scoped</a> to true.</p>

  <p><dfn id=element-definition>Element definition</dfn> is a process of adding a <a href=#custom-element-definition id=custom-elements-api:custom-element-definition-4>custom element definition</a>
  to the <code id=custom-elements-api:customelementregistry-16><a href=#customelementregistry>CustomElementRegistry</a></code>. This is accomplished by the <code id=custom-elements-api:dom-customelementregistry-define-3><a href=#dom-customelementregistry-define>define()</a></code> method.</p>

  

  <p>The <dfn data-dfn-for=CustomElementRegistry id=dom-customelementregistry-define data-dfn-type=method><code>define(<var>name</var>, <var>constructor</var>,
  <var>options</var>)</code></dfn> method steps are:</p>

  <ol><li><p>If <a id=custom-elements-api:isconstructor href=https://tc39.es/ecma262/#sec-isconstructor data-x-internal=isconstructor>IsConstructor</a>(<var>constructor</var>) is false, then throw a
   <code id=custom-elements-api:typeerror><a data-x-internal=typeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-typeerror>TypeError</a></code>.<li><p>If <var>name</var> is not a <a href=#valid-custom-element-name id=custom-elements-api:valid-custom-element-name-3>valid custom element name</a>, then throw a
   <a id=custom-elements-api:syntaxerror-2 href=https://webidl.spec.whatwg.org/#syntaxerror data-x-internal=syntaxerror>"<code>SyntaxError</code>"</a> <code id=custom-elements-api:domexception-4><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <a id=custom-elements-api:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#custom-element-definition-set id=custom-elements-api:custom-element-definition-set>custom element definition set</a> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-api:list-contains data-x-internal=list-contains>contains</a> an item with <a href=#concept-custom-element-definition-name id=custom-elements-api:concept-custom-element-definition-name-4>name</a> <var>name</var>, then throw a
   <a id=custom-elements-api:notsupportederror-3 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=custom-elements-api:domexception-5><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <a id=custom-elements-api:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#custom-element-definition-set id=custom-elements-api:custom-element-definition-set-2>custom element definition set</a> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-api:list-contains-2 data-x-internal=list-contains>contains</a> an item with <a href=#concept-custom-element-definition-constructor id=custom-elements-api:concept-custom-element-definition-constructor-4>constructor</a> <var>constructor</var>,
   then throw a <a id=custom-elements-api:notsupportederror-4 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=custom-elements-api:domexception-6><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>localName</var> be <var>name</var>.<li><p>Let <var>extends</var> be <var>options</var>["<code id=custom-elements-api:dom-elementdefinitionoptions-extends><a href=#dom-elementdefinitionoptions-extends>extends</a></code>"] if it <a href=https://infra.spec.whatwg.org/#map-exists id=custom-elements-api:map-exists data-x-internal=map-exists>exists</a>; otherwise null.<li>
    <p>If <var>extends</var> is not null:</p>

    <ol><li><p>If <a id=custom-elements-api:this-6 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#is-scoped id=custom-elements-api:is-scoped-2>is scoped</a> is true, then throw a
     <a id=custom-elements-api:notsupportederror-5 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=custom-elements-api:domexception-7><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <var>extends</var> is a <a href=#valid-custom-element-name id=custom-elements-api:valid-custom-element-name-4>valid custom element name</a>, then throw a
     <a id=custom-elements-api:notsupportederror-6 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=custom-elements-api:domexception-8><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If the <a id=custom-elements-api:element-interface href=https://dom.spec.whatwg.org/#concept-element-interface data-x-internal=element-interface>element interface</a> for <var>extends</var> and the <a id=custom-elements-api:html-namespace-2 href=https://infra.spec.whatwg.org/#html-namespace data-x-internal=html-namespace-2>HTML
     namespace</a> is <code id=custom-elements-api:htmlunknownelement><a href=dom.html#htmlunknownelement>HTMLUnknownElement</a></code> (e.g., if <var>extends</var> does not
     indicate an element definition in this specification), then throw a
     <a id=custom-elements-api:notsupportederror-7 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=custom-elements-api:domexception-9><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Set <var>localName</var> to <var>extends</var>.</ol>
   <li><p>If <a id=custom-elements-api:this-7 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#element-definition-is-running id=custom-elements-api:element-definition-is-running>element definition is running</a> is true, then throw
   a <a id=custom-elements-api:notsupportederror-8 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=custom-elements-api:domexception-10><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Set <a id=custom-elements-api:this-8 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#element-definition-is-running id=custom-elements-api:element-definition-is-running-2>element definition is running</a> to true.<li><p>Let <var>formAssociated</var> be false.<li><p>Let <var>disableInternals</var> be false.

   <li><p>Let <var>disableShadow</var> be false.

   <li><p>Let <var>observedAttributes</var> be an empty <code>sequence&lt;DOMString></code>.<li>
    <p>Run the following steps while catching any exceptions:</p>

    <ol><li><p>Let <var>prototype</var> be ? <a href=https://tc39.es/ecma262/#sec-get-o-p id=custom-elements-api:js-get data-x-internal=js-get>Get</a>(<var>constructor</var>,
     "prototype").<li><p>If <var>prototype</var> <a href=https://tc39.es/ecma262/#sec-object-type id=custom-elements-api:js-object data-x-internal=js-object>is not an Object</a>, then throw a
     <code id=custom-elements-api:typeerror-2><a data-x-internal=typeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-typeerror>TypeError</a></code> exception.<li><p>Let <var>lifecycleCallbacks</var> be the <a id=custom-elements-api:ordered-map-3 href=https://infra.spec.whatwg.org/#ordered-map data-x-internal=ordered-map>ordered map</a> «[ "<code>connectedCallback</code>" → null, "<code>disconnectedCallback</code>" →
     null, "<code>adoptedCallback</code>" → null, "<code>connectedMoveCallback</code>" → null, "<code>attributeChangedCallback</code>" → null ]».</p>

     <li>
      <p>For each <var>callbackName</var> of <a href=https://infra.spec.whatwg.org/#map-getting-the-keys id=custom-elements-api:map-get-the-keys data-x-internal=map-get-the-keys>the keys</a> of
      <var>lifecycleCallbacks</var>:</p>

      <ol><li><p>Let <var>callbackValue</var> be ? <a href=https://tc39.es/ecma262/#sec-get-o-p id=custom-elements-api:js-get-2 data-x-internal=js-get>Get</a>(<var>prototype</var>,
       <var>callbackName</var>).</p>

       <li><p>If <var>callbackValue</var> is not undefined, then <a href=https://infra.spec.whatwg.org/#map-set id=custom-elements-api:map-set data-x-internal=map-set>set</a>
       <var>lifecycleCallbacks</var>[<var>callbackName</var>] to the result of <a href=https://webidl.spec.whatwg.org/#es-type-mapping id=custom-elements-api:concept-idl-convert data-x-internal=concept-idl-convert>converting</a> <var>callbackValue</var> to the Web IDL <code id=custom-elements-api:idl-function><a data-x-internal=idl-function href=https://webidl.spec.whatwg.org/#common-Function>Function</a></code> callback type.</ol>
     <li>
      <p>If <var>lifecycleCallbacks</var>["<code>attributeChangedCallback</code>"] is not
      null:</p>

      <ol><li><p>Let <var>observedAttributesIterable</var> be ? <a href=https://tc39.es/ecma262/#sec-get-o-p id=custom-elements-api:js-get-3 data-x-internal=js-get>Get</a>(<var>constructor</var>, "observedAttributes").<li><p>If <var>observedAttributesIterable</var> is not undefined, then set
       <var>observedAttributes</var> to the result of <a href=https://webidl.spec.whatwg.org/#es-type-mapping id=custom-elements-api:concept-idl-convert-2 data-x-internal=concept-idl-convert>converting</a> <var>observedAttributesIterable</var> to a
       <code>sequence&lt;DOMString></code>. Rethrow any exceptions from the
       conversion.</ol>

     <li><p>Let <var>disabledFeatures</var> be an empty <code>sequence&lt;DOMString></code>.<li><p>Let <var>disabledFeaturesIterable</var> be ? <a href=https://tc39.es/ecma262/#sec-get-o-p id=custom-elements-api:js-get-4 data-x-internal=js-get>Get</a>(<var>constructor</var>, "disabledFeatures").<li><p>If <var>disabledFeaturesIterable</var> is not undefined, then set
     <var>disabledFeatures</var> to the result of <a href=https://webidl.spec.whatwg.org/#es-type-mapping id=custom-elements-api:concept-idl-convert-3 data-x-internal=concept-idl-convert>converting</a> <var>disabledFeaturesIterable</var> to a <code>sequence&lt;DOMString></code>. Rethrow any exceptions from the conversion.<li><p>If <var>disabledFeatures</var> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-api:list-contains-3 data-x-internal=list-contains>contains</a> "<code>internals</code>", then set <var>disableInternals</var> to true.<li><p>If <var>disabledFeatures</var> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-api:list-contains-4 data-x-internal=list-contains>contains</a> "<code>shadow</code>", then set <var>disableShadow</var> to true.<li><p>Let <var>formAssociatedValue</var> be ? <a href=https://tc39.es/ecma262/#sec-get-o-p id=custom-elements-api:js-get-5 data-x-internal=js-get>Get</a>(
     <var>constructor</var>, "formAssociated").<li><p>Set <var>formAssociated</var> to the result of <a href=https://webidl.spec.whatwg.org/#es-type-mapping id=custom-elements-api:concept-idl-convert-4 data-x-internal=concept-idl-convert>converting</a> <var>formAssociatedValue</var> to a <code>boolean</code>.<li>
      <p>If <var>formAssociated</var> is true, then for each <var>callbackName</var> of « "<code>formAssociatedCallback</code>", "<code>formResetCallback</code>", "<code>formDisabledCallback</code>", "<code>formStateRestoreCallback</code>"
      »:</p>

      <ol><li><p>Let <var>callbackValue</var> be ? <a href=https://tc39.es/ecma262/#sec-get-o-p id=custom-elements-api:js-get-6 data-x-internal=js-get>Get</a>(<var>prototype</var>,
       <var>callbackName</var>).<li><p>If <var>callbackValue</var> is not undefined, then <a href=https://infra.spec.whatwg.org/#map-set id=custom-elements-api:map-set-2 data-x-internal=map-set>set</a>
       <var>lifecycleCallbacks</var>[<var>callbackName</var>] to the result of <a href=https://webidl.spec.whatwg.org/#es-type-mapping id=custom-elements-api:concept-idl-convert-5 data-x-internal=concept-idl-convert>converting</a> <var>callbackValue</var> to the Web IDL <code id=custom-elements-api:idl-function-2><a data-x-internal=idl-function href=https://webidl.spec.whatwg.org/#common-Function>Function</a></code> callback type.</ol>
     </ol>

    <p>Then, regardless of whether the above steps threw an exception or not: set
    <a id=custom-elements-api:this-9 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#element-definition-is-running id=custom-elements-api:element-definition-is-running-3>element definition is running</a> to false.</p>

    <p>Finally, if the steps threw an exception, rethrow that exception.</p>
   <li><p>Let <var>definition</var> be a new <a href=#custom-element-definition id=custom-elements-api:custom-element-definition-5>custom element definition</a> with <a href=#concept-custom-element-definition-name id=custom-elements-api:concept-custom-element-definition-name-5>name</a> <var>name</var>, <a href=#concept-custom-element-definition-local-name id=custom-elements-api:concept-custom-element-definition-local-name-2>local name</a> <var>localName</var>,
   <a href=#concept-custom-element-definition-constructor id=custom-elements-api:concept-custom-element-definition-constructor-5>constructor</a>
   <var>constructor</var>, <a href=#concept-custom-element-definition-observed-attributes id=custom-elements-api:concept-custom-element-definition-observed-attributes>observed attributes</a>
   <var>observedAttributes</var>, <a href=#concept-custom-element-definition-lifecycle-callbacks id=custom-elements-api:concept-custom-element-definition-lifecycle-callbacks>lifecycle callbacks</a>
   <var>lifecycleCallbacks</var>,
   <a href=#concept-custom-element-definition-form-associated id=custom-elements-api:concept-custom-element-definition-form-associated>form-associated</a>
   <var>formAssociated</var>, <a href=#concept-custom-element-definition-disable-internals id=custom-elements-api:concept-custom-element-definition-disable-internals>disable internals</a>
   <var>disableInternals</var>, and <a href=#concept-custom-element-definition-disable-shadow id=custom-elements-api:concept-custom-element-definition-disable-shadow>disable shadow</a>
   <var>disableShadow</var>.<li><p><a href=https://infra.spec.whatwg.org/#set-append id=custom-elements-api:set-append data-x-internal=set-append>Append</a> <var>definition</var> to <a id=custom-elements-api:this-10 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s
   <a href=#custom-element-definition-set id=custom-elements-api:custom-element-definition-set-3>custom element definition set</a>.<li><p>If <a id=custom-elements-api:this-11 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#is-scoped id=custom-elements-api:is-scoped-3>is scoped</a> is true, then for each <var>document</var>
   of <a id=custom-elements-api:this-12 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#scoped-document-set id=custom-elements-api:scoped-document-set>scoped document set</a>: <a href=#upgrade-particular-elements-within-a-document id=custom-elements-api:upgrade-particular-elements-within-a-document>upgrade particular elements within
   a document</a> given <a id=custom-elements-api:this-13 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>, <var>document</var>, <var>definition</var>, and
   <var>localName</var>.<li><p>Otherwise, <a href=#upgrade-particular-elements-within-a-document id=custom-elements-api:upgrade-particular-elements-within-a-document-2>upgrade particular elements within a document</a> given
   <a id=custom-elements-api:this-14 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>, <a id=custom-elements-api:this-15 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=custom-elements-api:concept-relevant-global href=webappapis.html#concept-relevant-global>relevant global object</a>'s <a href=nav-history-apis.html#concept-document-window id=custom-elements-api:concept-document-window-4>associated <code>Document</code></a>, <var>definition</var>,
   <var>localName</var>, and <var>name</var>.<li>
    <p>If <a id=custom-elements-api:this-16 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#when-defined-promise-map id=custom-elements-api:when-defined-promise-map>when-defined promise map</a>[<var>name</var>] <a href=https://infra.spec.whatwg.org/#map-exists id=custom-elements-api:map-exists-2 data-x-internal=map-exists>exists</a>:</p>

    <ol><li><p>Resolve <a id=custom-elements-api:this-17 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#when-defined-promise-map id=custom-elements-api:when-defined-promise-map-2>when-defined promise map</a>[<var>name</var>] with
     <var>constructor</var>.<li><p><a href=https://infra.spec.whatwg.org/#map-remove id=custom-elements-api:map-remove data-x-internal=map-remove>Remove</a> <a id=custom-elements-api:this-18 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#when-defined-promise-map id=custom-elements-api:when-defined-promise-map-3>when-defined promise
     map</a>[<var>name</var>].</ol>
   </ol>

  <p>To <dfn id=upgrade-particular-elements-within-a-document>upgrade particular elements within a document</dfn> given a
  <code id=custom-elements-api:customelementregistry-17><a href=#customelementregistry>CustomElementRegistry</a></code> object <var>registry</var>, a <code id=custom-elements-api:document-5><a href=dom.html#document>Document</a></code> object
  <var>document</var>, a <a href=#custom-element-definition id=custom-elements-api:custom-element-definition-6>custom element definition</a> <var>definition</var>, a string
  <var>localName</var>, and optionally a string <var>name</var> (default <var>localName</var>):</p>

  <ol><li><p>Let <var>upgradeCandidates</var> be all elements that are <a href=https://dom.spec.whatwg.org/#concept-shadow-including-descendant id=custom-elements-api:shadow-including-descendant data-x-internal=shadow-including-descendant>shadow-including descendants</a> of <var>document</var>, whose <a href=https://dom.spec.whatwg.org/#element-custom-element-registry id=custom-elements-api:element-custom-element-registry-2 data-x-internal=element-custom-element-registry>custom element registry</a> is <var>registry</var>,
   whose namespace is the <a id=custom-elements-api:html-namespace-2-2 href=https://infra.spec.whatwg.org/#html-namespace data-x-internal=html-namespace-2>HTML namespace</a>, and whose local name is <var>localName</var>,
   in <a id=custom-elements-api:shadow-including-tree-order href=https://dom.spec.whatwg.org/#concept-shadow-including-tree-order data-x-internal=shadow-including-tree-order>shadow-including tree order</a>. Additionally, if <var>name</var> is not
   <var>localName</var>, only include elements whose <a href=https://dom.spec.whatwg.org/#concept-element-is-value id=custom-elements-api:concept-element-is-value data-x-internal=concept-element-is-value><code>is</code> value</a> is equal to <var>name</var>.<li><p>For each element <var>element</var> of <var>upgradeCandidates</var>: <a href=#enqueue-a-custom-element-upgrade-reaction id=custom-elements-api:enqueue-a-custom-element-upgrade-reaction>enqueue a
   custom element upgrade reaction</a> given <var>element</var> and
   <var>definition</var>.</ol>
  

  <p>The <dfn data-dfn-for=CustomElementRegistry id=dom-customelementregistry-get data-dfn-type=method><code>get(<var>name</var>)</code></dfn> method steps are:</p>

  <ol><li><p>If <a id=custom-elements-api:this-19 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#custom-element-definition-set id=custom-elements-api:custom-element-definition-set-4>custom element definition set</a> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-api:list-contains-5 data-x-internal=list-contains>contains</a> an item with <a href=#concept-custom-element-definition-name id=custom-elements-api:concept-custom-element-definition-name-6>name</a> <var>name</var>, then return that
   item's <a href=#concept-custom-element-definition-constructor id=custom-elements-api:concept-custom-element-definition-constructor-6>constructor</a>.<li><p>Return undefined.</ol>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/getName title="The getName() method of the CustomElementRegistry interface returns the name for a previously-defined custom element.">CustomElementRegistry/getName</a><div class=support><span class="firefox yes"><span>Firefox</span><span>116+</span></span><span class="safari yes"><span>Safari</span><span title="Partial implementation.">🔰 preview+</span></span><span class="chrome yes"><span>Chrome</span><span>117+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>117+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <dfn data-dfn-for=CustomElementRegistry id=dom-customelementregistry-getname data-dfn-type=method><code>getName(<var>constructor</var>)</code></dfn> method
  steps are:</p>

  <ol><li><p>If <a id=custom-elements-api:this-20 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#custom-element-definition-set id=custom-elements-api:custom-element-definition-set-5>custom element definition set</a> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-api:list-contains-6 data-x-internal=list-contains>contains</a> an item with <a href=#concept-custom-element-definition-constructor id=custom-elements-api:concept-custom-element-definition-constructor-7>constructor</a>
   <var>constructor</var>, then return that item's <a href=#concept-custom-element-definition-name id=custom-elements-api:concept-custom-element-definition-name-7>name</a>.<li><p>Return null.</ol>

  <p>The <dfn data-dfn-for=CustomElementRegistry id=dom-customelementregistry-whendefined data-dfn-type=method><code>whenDefined(<var>name</var>)</code></dfn> method
  steps are:</p>

  <ol><li><p>If <var>name</var> is not a <a href=#valid-custom-element-name id=custom-elements-api:valid-custom-element-name-5>valid custom element name</a>, then return <a id=custom-elements-api:a-promise-rejected-with href=https://webidl.spec.whatwg.org/#a-promise-rejected-with data-x-internal=a-promise-rejected-with>a
   promise rejected with</a> a <a id=custom-elements-api:syntaxerror-3 href=https://webidl.spec.whatwg.org/#syntaxerror data-x-internal=syntaxerror>"<code>SyntaxError</code>"</a>
   <code id=custom-elements-api:domexception-11><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <a id=custom-elements-api:this-21 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#custom-element-definition-set id=custom-elements-api:custom-element-definition-set-6>custom element definition set</a> <a href=https://infra.spec.whatwg.org/#list-contain id=custom-elements-api:list-contains-7 data-x-internal=list-contains>contains</a> an item with <a href=#concept-custom-element-definition-name id=custom-elements-api:concept-custom-element-definition-name-8>name</a> <var>name</var>, then return <a id=custom-elements-api:a-promise-resolved-with href=https://webidl.spec.whatwg.org/#a-promise-resolved-with data-x-internal=a-promise-resolved-with>a
   promise resolved with</a> that item's <a href=#concept-custom-element-definition-constructor id=custom-elements-api:concept-custom-element-definition-constructor-8>constructor</a>.<li><p>If <a id=custom-elements-api:this-22 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#when-defined-promise-map id=custom-elements-api:when-defined-promise-map-4>when-defined promise map</a>[<var>name</var>] does not
   <a href=https://infra.spec.whatwg.org/#map-exists id=custom-elements-api:map-exists-3 data-x-internal=map-exists>exist</a>, then <a href=https://infra.spec.whatwg.org/#map-set id=custom-elements-api:map-set-3 data-x-internal=map-set>set</a>
   <a id=custom-elements-api:this-23 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#when-defined-promise-map id=custom-elements-api:when-defined-promise-map-5>when-defined promise map</a>[<var>name</var>] to a new
   promise.<li><p>Return <a id=custom-elements-api:this-24 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#when-defined-promise-map id=custom-elements-api:when-defined-promise-map-6>when-defined promise
   map</a>[<var>name</var>].</ol>

  

  <div class=example>
   <p>The <code id=custom-elements-api:dom-customelementregistry-whendefined-3><a href=#dom-customelementregistry-whendefined>whenDefined()</a></code> method can be
   used to avoid performing an action until all appropriate <a href=#custom-element id=custom-elements-api:custom-element-8>custom
   elements</a> are <a href=https://dom.spec.whatwg.org/#concept-element-defined id=custom-elements-api:concept-element-defined data-x-internal=concept-element-defined>defined</a>. In this example, we
   combine it with the <code id=custom-elements-api:selector-defined><a href=semantics-other.html#selector-defined>:defined</a></code> pseudo-class to hide a
   dynamically-loaded article's contents until we're sure that all of the <a href=#autonomous-custom-element id=custom-elements-api:autonomous-custom-element-2>autonomous custom elements</a> it uses are defined.</p>

   <pre><code class='js'>articleContainer<c- p>.</c->hidden <c- o>=</c-> <c- kc>true</c-><c- p>;</c->

fetch<c- p>(</c->articleURL<c- p>)</c->
  <c- p>.</c->then<c- p>(</c->response <c- p>=&gt;</c-> response<c- p>.</c->text<c- p>())</c->
  <c- p>.</c->then<c- p>(</c->text <c- p>=&gt;</c-> <c- p>{</c->
    articleContainer<c- p>.</c->innerHTML <c- o>=</c-> text<c- p>;</c->

    <c- k>return</c-> Promise<c- p>.</c->all<c- p>(</c->
      <c- p>[...</c->articleContainer<c- p>.</c->querySelectorAll<c- p>(</c-><c- u>&quot;:not(:defined)&quot;</c-><c- p>)]</c->
        <c- p>.</c->map<c- p>(</c->el <c- p>=&gt;</c-> customElements<c- p>.</c->whenDefined<c- p>(</c->el<c- p>.</c->localName<c- p>))</c->
    <c- p>);</c->
  <c- p>})</c->
  <c- p>.</c->then<c- p>(()</c-> <c- p>=&gt;</c-> <c- p>{</c->
    articleContainer<c- p>.</c->hidden <c- o>=</c-> <c- kc>false</c-><c- p>;</c->
  <c- p>});</c-></code></pre>
  </div>

  

  <p>The <dfn data-dfn-for=CustomElementRegistry id=dom-customelementregistry-upgrade data-dfn-type=method><code>upgrade(<var>root</var>)</code></dfn> method steps
  are:</p>

  <ol><li><p>Let <var>candidates</var> be a <a id=custom-elements-api:list href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of all of <var>root</var>'s
   <a id=custom-elements-api:shadow-including-inclusive-descendant-2 href=https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant data-x-internal=shadow-including-inclusive-descendant>shadow-including inclusive descendant</a> elements, in <a id=custom-elements-api:shadow-including-tree-order-2 href=https://dom.spec.whatwg.org/#concept-shadow-including-tree-order data-x-internal=shadow-including-tree-order>shadow-including tree
   order</a>.<li><p><a href=https://infra.spec.whatwg.org/#list-iterate id=custom-elements-api:list-iterate data-x-internal=list-iterate>For each</a> <var>candidate</var> of <var>candidates</var>,
   <a href=#concept-try-upgrade id=custom-elements-api:concept-try-upgrade-2>try to upgrade</a> <var>candidate</var>.</ol>

  

  <div class=example>
   <p>The <code id=custom-elements-api:dom-customelementregistry-upgrade-2><a href=#dom-customelementregistry-upgrade>upgrade()</a></code> method allows upgrading
   of elements at will. Normally elements are automatically upgraded when they become
   <a id=custom-elements-api:connected-2 href=https://dom.spec.whatwg.org/#connected data-x-internal=connected>connected</a>, but this method can be used if you need to upgrade before you're ready to
   connect the element.</p>

   <pre><code class='js'><c- a>const</c-> el <c- o>=</c-> document<c- p>.</c->createElement<c- p>(</c-><c- u>&quot;spider-man&quot;</c-><c- p>);</c->

<c- a>class</c-> SpiderMan <c- k>extends</c-> HTMLElement <c- p>{}</c->
customElements<c- p>.</c->define<c- p>(</c-><c- u>&quot;spider-man&quot;</c-><c- p>,</c-> SpiderMan<c- p>);</c->

console<c- p>.</c->assert<c- p>(</c-><c- o>!</c-><c- p>(</c->el <c- k>instanceof</c-> SpiderMan<c- p>));</c-> <c- c1>// not yet upgraded</c->

customElements<c- p>.</c->upgrade<c- p>(</c->el<c- p>);</c->
console<c- p>.</c->assert<c- p>(</c->el <c- k>instanceof</c-> SpiderMan<c- p>);</c->    <c- c1>// upgraded!</c-></code></pre>
  </div>

  

  <p>The <dfn data-dfn-for=CustomElementRegistry id=dom-customelementregistry-initialize data-dfn-type=method><code>initialize(<var>root</var>)</code></dfn> method
  steps are:</p>

  <ol><li><p>If <a id=custom-elements-api:this-25 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#is-scoped id=custom-elements-api:is-scoped-4>is scoped</a> is false and either <var>root</var> is a
   <code id=custom-elements-api:document-6><a href=dom.html#document>Document</a></code> node or <var>root</var>'s <a id=custom-elements-api:node-document-2 href=https://dom.spec.whatwg.org/#concept-node-document data-x-internal=node-document>node document</a>'s <a href=https://dom.spec.whatwg.org/#document-custom-element-registry id=custom-elements-api:document-custom-element-registry-5 data-x-internal=document-custom-element-registry>custom element registry</a> is not
   <a id=custom-elements-api:this-26 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>, then throw a <a id=custom-elements-api:notsupportederror-9 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a>
   <code id=custom-elements-api:domexception-12><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <var>root</var> is a <code id=custom-elements-api:document-7><a href=dom.html#document>Document</a></code> node whose <a href=https://dom.spec.whatwg.org/#document-custom-element-registry id=custom-elements-api:document-custom-element-registry-6 data-x-internal=document-custom-element-registry>custom element registry</a> is null, then set
   <var>root</var>'s <a href=https://dom.spec.whatwg.org/#document-custom-element-registry id=custom-elements-api:document-custom-element-registry-7 data-x-internal=document-custom-element-registry>custom element registry</a>
   to <a id=custom-elements-api:this-27 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.<li><p>Otherwise, if <var>root</var> is a <code id=custom-elements-api:shadowroot-2><a data-x-internal=shadowroot href=https://dom.spec.whatwg.org/#interface-shadowroot>ShadowRoot</a></code> node whose <a href=https://dom.spec.whatwg.org/#shadowroot-custom-element-registry id=custom-elements-api:shadow-root-custom-element-registry-2 data-x-internal=shadow-root-custom-element-registry>custom element registry</a> is null, then set
   <var>root</var>'s <a href=https://dom.spec.whatwg.org/#shadowroot-custom-element-registry id=custom-elements-api:shadow-root-custom-element-registry-3 data-x-internal=shadow-root-custom-element-registry>custom element
   registry</a> to <a id=custom-elements-api:this-28 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.<li>
    <p>For each <a id=custom-elements-api:inclusive-descendant-2 href=https://dom.spec.whatwg.org/#concept-tree-inclusive-descendant data-x-internal=inclusive-descendant>inclusive descendant</a> <var>inclusiveDescendant</var> of <var>root</var>:
    if <var>inclusiveDescendant</var> is an <code id=custom-elements-api:element-2><a data-x-internal=element href=https://dom.spec.whatwg.org/#interface-element>Element</a></code> node whose <a href=https://dom.spec.whatwg.org/#element-custom-element-registry id=custom-elements-api:element-custom-element-registry-3 data-x-internal=element-custom-element-registry>custom element registry</a> is null:</p>

    <ol><li><p>Set <var>inclusiveDescendant</var>'s <a href=https://dom.spec.whatwg.org/#element-custom-element-registry id=custom-elements-api:element-custom-element-registry-4 data-x-internal=element-custom-element-registry>custom element registry</a> to
     <a id=custom-elements-api:this-29 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.<li><p>If <a id=custom-elements-api:this-30 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#is-scoped id=custom-elements-api:is-scoped-5>is scoped</a> is true, then <a href=https://infra.spec.whatwg.org/#set-append id=custom-elements-api:set-append-2 data-x-internal=set-append>append</a> <var>inclusiveDescendant</var>'s <a id=custom-elements-api:node-document-3 href=https://dom.spec.whatwg.org/#concept-node-document data-x-internal=node-document>node document</a> to
     <a id=custom-elements-api:this-31 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#scoped-document-set id=custom-elements-api:scoped-document-set-2>scoped document set</a>.</ol>
   </ol>

  <p class=note>Once the custom element registry of a node is initialized to a
  <code id=custom-elements-api:customelementregistry-18><a href=#customelementregistry>CustomElementRegistry</a></code> object, it intentionally cannot be changed any further. This
  simplifies reasoning about code and allows implementations to optimize.</p>


  <h4 id=upgrades><span class=secno>4.13.5</span> <dfn>Upgrades</dfn><a href=#upgrades class=self-link></a></h4>

  <p>To <dfn id=concept-upgrade-an-element data-export="">upgrade an element</dfn>, given as input a
  <a href=#custom-element-definition id=upgrades:custom-element-definition>custom element definition</a> <var>definition</var> and an element <var>element</var>,
  run the following steps:</p>

  <ol><li id=concept-upgrade-an-element-early-exit>
    <p>If <var>element</var>'s <a id=upgrades:custom-element-state href=https://dom.spec.whatwg.org/#concept-element-custom-element-state data-x-internal=custom-element-state>custom element state</a> is not "<code>undefined</code>" or "<code>uncustomized</code>", then return.</p>

    <div class=example>
     <p>One scenario where this can occur due to reentrant invocation of this algorithm, as in the
     following example:</p>

     <pre><code class='html'><c- cp>&lt;!DOCTYPE html&gt;</c->
<c- p>&lt;</c-><c- f>x-foo</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;a&quot;</c-><c- p>&gt;&lt;/</c-><c- f>x-foo</c-><c- p>&gt;</c->
<c- p>&lt;</c-><c- f>x-foo</c-> <c- e>id</c-><c- o>=</c-><c- s>&quot;b&quot;</c-><c- p>&gt;&lt;/</c-><c- f>x-foo</c-><c- p>&gt;</c->

<c- p>&lt;</c-><c- f>script</c-><c- p>&gt;</c->
<c- c1>// Defining enqueues upgrade reactions for both &quot;a&quot; and &quot;b&quot;</c->
customElements<c- p>.</c->define<c- p>(</c-><c- u>&quot;x-foo&quot;</c-><c- p>,</c-> <c- a>class</c-> <c- k>extends</c-> HTMLElement <c- p>{</c->
  constructor<c- p>()</c-> <c- p>{</c->
    <c- k>super</c-><c- p>();</c->

    <c- a>const</c-> b <c- o>=</c-> document<c- p>.</c->querySelector<c- p>(</c-><c- u>&quot;#b&quot;</c-><c- p>);</c->
    b<c- p>.</c->remove<c- p>();</c->

    <c- c1>// While this constructor is running for &quot;a&quot;, &quot;b&quot; is still</c->
    <c- c1>// undefined, and so inserting it into the document will enqueue a</c->
    <c- c1>// second upgrade reaction for &quot;b&quot; in addition to the one enqueued</c->
    <c- c1>// by defining x-foo.</c->
    document<c- p>.</c->body<c- p>.</c->appendChild<c- p>(</c->b<c- p>);</c->
  <c- p>}</c->
<c- p>})</c->
<c- p>&lt;/</c-><c- f>script</c-><c- p>&gt;</c-></code></pre>

     <p>This step will thus bail out the algorithm early when <a href=#concept-upgrade-an-element id=upgrades:concept-upgrade-an-element>upgrade an element</a> is invoked
     with "<code>b</code>" a second time.</p>
    </div>
   <li><p>Set <var>element</var>'s <a href=https://dom.spec.whatwg.org/#concept-element-custom-element-definition id=upgrades:concept-element-custom-element-definition data-x-internal=concept-element-custom-element-definition>custom
   element definition</a> to <var>definition</var>.<li>
    <p>Set <var>element</var>'s <a id=upgrades:custom-element-state-2 href=https://dom.spec.whatwg.org/#concept-element-custom-element-state data-x-internal=custom-element-state>custom element state</a> to "<code>failed</code>".</p>

    <p class=note>It will be set to "<code>custom</code>" <a href=#concept-upgrade-an-element-set-state-to-custom>after the upgrade succeeds</a>. For now,
    we set it to "<code>failed</code>" so that any reentrant invocations will hit <a href=#concept-upgrade-an-element-early-exit>the above early-exit step</a>.</p>
   <li><p>For each <var>attribute</var> in <var>element</var>'s <a id=upgrades:attribute-list href=https://dom.spec.whatwg.org/#concept-element-attribute data-x-internal=attribute-list>attribute list</a>, in
   order, <a href=#enqueue-a-custom-element-callback-reaction id=upgrades:enqueue-a-custom-element-callback-reaction>enqueue a custom element callback reaction</a> with <var>element</var>, callback
   name "<code>attributeChangedCallback</code>", and « <var>attribute</var>'s local name,
   null, <var>attribute</var>'s value, <var>attribute</var>'s namespace ».<li><p>If <var>element</var> is <a id=upgrades:connected href=https://dom.spec.whatwg.org/#connected data-x-internal=connected>connected</a>, then <a href=#enqueue-a-custom-element-callback-reaction id=upgrades:enqueue-a-custom-element-callback-reaction-2>enqueue a custom element
   callback reaction</a> with <var>element</var>, callback name "<code>connectedCallback</code>", and « ».<li><p>Add <var>element</var> to the end of <var>definition</var>'s <a href=#concept-custom-element-definition-construction-stack id=upgrades:concept-custom-element-definition-construction-stack>construction stack</a>.<li><p>Let <var>C</var> be <var>definition</var>'s <a href=#concept-custom-element-definition-constructor id=upgrades:concept-custom-element-definition-constructor>constructor</a>.<li><p><a href=https://infra.spec.whatwg.org/#map-set id=upgrades:map-set data-x-internal=map-set>Set</a> the <a id=upgrades:surrounding-agent href=https://tc39.es/ecma262/#surrounding-agent data-x-internal=surrounding-agent>surrounding agent</a>'s <a href=#active-custom-element-constructor-map id=upgrades:active-custom-element-constructor-map>active custom
   element constructor map</a>[<var>C</var>] to <var>element</var>'s <a href=https://dom.spec.whatwg.org/#element-custom-element-registry id=upgrades:element-custom-element-registry data-x-internal=element-custom-element-registry>custom element registry</a>.<li>
    <p>Run the following steps while catching any exceptions:</p>

    <ol><li>
      <p>If <var>definition</var>'s <a href=#concept-custom-element-definition-disable-shadow id=upgrades:concept-custom-element-definition-disable-shadow>disable shadow</a> is true and
      <var>element</var>'s <a href=https://dom.spec.whatwg.org/#concept-element-shadow-root id=upgrades:concept-element-shadow-root data-x-internal=concept-element-shadow-root>shadow root</a> is
      non-null, then throw a <a id=upgrades:notsupportederror href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a>
      <code id=upgrades:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.</p>

      <p class=note>This is needed as <code id=upgrades:dom-element-attachshadow><a data-x-internal=dom-element-attachshadow href=https://dom.spec.whatwg.org/#dom-element-attachshadow>attachShadow()</a></code> does not use <a href=#look-up-a-custom-element-definition id=upgrades:look-up-a-custom-element-definition>look up a custom
      element definition</a> while <code id=upgrades:dom-attachinternals><a href=#dom-attachinternals>attachInternals()</a></code>
      does.</p>
     <li><p>Set <var>element</var>'s <a id=upgrades:custom-element-state-3 href=https://dom.spec.whatwg.org/#concept-element-custom-element-state data-x-internal=custom-element-state>custom element state</a> to "<code>precustomized</code>".<li>
      <p>Let <var>constructResult</var> be the result of <a href=https://webidl.spec.whatwg.org/#construct-a-callback-function id=upgrades:es-constructing-callback-functions data-x-internal=es-constructing-callback-functions>constructing</a> <var>C</var>, with no
      arguments.</p>

      <p class=note>If <var>C</var> <a href=#custom-element-conformance>non-conformantly</a>
      uses an API decorated with the <code id=upgrades:cereactions><a href=#cereactions>[CEReactions]</a></code> extended
      attribute, then the reactions enqueued at the beginning of this algorithm will execute during
      this step, before <var>C</var> finishes and control returns to this algorithm. Otherwise, they
      will execute after <var>C</var> and the rest of the upgrade process finishes.</p>
     <li>
      <p>If <a id=upgrades:samevalue href=https://tc39.es/ecma262/#sec-samevalue data-x-internal=samevalue>SameValue</a>(<var>constructResult</var>, <var>element</var>) is false, then
      throw a <code id=upgrades:typeerror><a data-x-internal=typeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-typeerror>TypeError</a></code>.</p>

      <p class=note>This can occur if <var>C</var> constructs another instance of the same custom
      element before calling <code>super()</code>, or if <var>C</var> uses JavaScript's
      <code>return</code>-override feature to return an arbitrary <code id=upgrades:htmlelement><a href=dom.html#htmlelement>HTMLElement</a></code>
      object from the constructor.</p>
     </ol>

    <p>Then, perform the following steps, regardless of whether the above steps threw an exception
    or not:</p>

    <ol><li>
      <p><a href=https://infra.spec.whatwg.org/#map-remove id=upgrades:map-remove data-x-internal=map-remove>Remove</a> the <a id=upgrades:surrounding-agent-2 href=https://tc39.es/ecma262/#surrounding-agent data-x-internal=surrounding-agent>surrounding agent</a>'s <a href=#active-custom-element-constructor-map id=upgrades:active-custom-element-constructor-map-2>active
      custom element constructor map</a>[<var>C</var>].</p>

      <p class=note>This is a no-op if <var>C</var> immediately calls <code>super()</code> as it ought to do.</p>
     <li>
      <p>Remove the last entry from the end of <var>definition</var>'s <a href=#concept-custom-element-definition-construction-stack id=upgrades:concept-custom-element-definition-construction-stack-2>construction stack</a>.</p>

      <div class=note>
       <p>Assuming <var>C</var> calls <code>super()</code> (as it will if it is <a href=#custom-element-conformance>conformant</a>), and that the call succeeds, this will be
       the <a href=#concept-already-constructed-marker id=upgrades:concept-already-constructed-marker><i>already
       constructed</i> marker</a> that replaced the <var>element</var> we pushed at the beginning
       of this algorithm. (The <a href=dom.html#html-element-constructors>HTML element constructor</a>
       carries out this replacement.)</p>

       <p>If <var>C</var> does not call <code>super()</code> (i.e. it is not <a href=#custom-element-conformance>conformant</a>), or if any step in the <a href=dom.html#html-element-constructors>HTML element constructor</a> throws, then this entry will
       still be <var>element</var>.</p>
      </div>
     </ol>

    <p>Finally, if the above steps threw an exception, then:</p>

    <ol><li><p>Set <var>element</var>'s <a href=https://dom.spec.whatwg.org/#concept-element-custom-element-definition id=upgrades:concept-element-custom-element-definition-2 data-x-internal=concept-element-custom-element-definition>custom
     element definition</a> to null.<li><p>Empty <var>element</var>'s <a href=#custom-element-reaction-queue id=upgrades:custom-element-reaction-queue>custom element reaction queue</a>.</p>

     <li><p>Rethrow the exception (thus terminating this algorithm).</ol>

    <p class=note>If the above steps threw an exception, then <var>element</var>'s <a id=upgrades:custom-element-state-4 href=https://dom.spec.whatwg.org/#concept-element-custom-element-state data-x-internal=custom-element-state>custom
    element state</a> will remain "<code>failed</code>" or "<code>precustomized</code>".</p>
   <li>
    <p>If <var>element</var> is a <a href=#form-associated-custom-element id=upgrades:form-associated-custom-element>form-associated custom element</a>, then:</p>
    <ol><li><p><a id=upgrades:reset-the-form-owner href=form-control-infrastructure.html#reset-the-form-owner>Reset the form owner</a> of <var>element</var>. If <var>element</var> is
     associated with a <code id=upgrades:the-form-element><a href=forms.html#the-form-element>form</a></code> element, then
     <a href=#enqueue-a-custom-element-callback-reaction id=upgrades:enqueue-a-custom-element-callback-reaction-3>enqueue a custom element callback reaction</a> with <var>element</var>, callback
     name "<code>formAssociatedCallback</code>", and « the associated <code id=upgrades:the-form-element-2><a href=forms.html#the-form-element>form</a></code>
     ».<li><p>If <var>element</var> is <a href=form-control-infrastructure.html#concept-fe-disabled id=upgrades:concept-fe-disabled>disabled</a>, then
     <a href=#enqueue-a-custom-element-callback-reaction id=upgrades:enqueue-a-custom-element-callback-reaction-4>enqueue a custom element callback reaction</a> with <var>element</var>, callback name
     "<code>formDisabledCallback</code>", and « true ».</ol>
   <li id=concept-upgrade-an-element-set-state-to-custom><p>Set <var>element</var>'s <a id=upgrades:custom-element-state-5 href=https://dom.spec.whatwg.org/#concept-element-custom-element-state data-x-internal=custom-element-state>custom
   element state</a> to "<code>custom</code>".</ol>

  <p>To <dfn id=concept-try-upgrade data-export="">try to upgrade an element</dfn> given an element
  <var>element</var>:</p>

  <ol><li><p>Let <var>definition</var> be the result of <a href=#look-up-a-custom-element-definition id=upgrades:look-up-a-custom-element-definition-2>looking up a custom element definition</a> given <var>element</var>'s <a href=https://dom.spec.whatwg.org/#element-custom-element-registry id=upgrades:element-custom-element-registry-2 data-x-internal=element-custom-element-registry>custom element registry</a>, <var>element</var>'s
   <a href=https://dom.spec.whatwg.org/#concept-element-namespace id=upgrades:concept-element-namespace data-x-internal=concept-element-namespace>namespace</a>, <var>element</var>'s <a href=https://dom.spec.whatwg.org/#concept-element-local-name id=upgrades:concept-element-local-name data-x-internal=concept-element-local-name>local name</a>, and <var>element</var>'s <a href=https://dom.spec.whatwg.org/#concept-element-is-value id=upgrades:concept-element-is-value data-x-internal=concept-element-is-value><code>is</code> value</a>.<li><p>If <var>definition</var> is not null, then <a href=#enqueue-a-custom-element-upgrade-reaction id=upgrades:enqueue-a-custom-element-upgrade-reaction>enqueue a custom element upgrade
   reaction</a> given <var>element</var> and <var>definition</var>.</ol>

  

  <h4 id=custom-element-reactions><span class=secno>4.13.6</span> Custom element reactions<a href=#custom-element-reactions class=self-link></a></h4>

  <p>A <a href=#custom-element id=custom-element-reactions:custom-element>custom element</a> possesses the ability to respond to certain occurrences by
  running author code:</p>

  <ul><li><p>When <a href=#upgrades id=custom-element-reactions:upgrades>upgraded</a>, its <a href=#custom-element-constructor id=custom-element-reactions:custom-element-constructor>constructor</a> is run, with no arguments.<li><p>When it <a id=custom-element-reactions:becomes-connected href=infrastructure.html#becomes-connected>becomes connected</a>, its <code>connectedCallback</code> is
   called, with no arguments.<li><p>When it <a id=custom-element-reactions:becomes-disconnected href=infrastructure.html#becomes-disconnected>becomes disconnected</a>, its <code>disconnectedCallback</code>
   is called, with no arguments.<li><p>When it is <a href=https://dom.spec.whatwg.org/#concept-node-move-ext id=custom-element-reactions:concept-node-move-ext data-x-internal=concept-node-move-ext>moved</a>, its <code>connectedMoveCallback</code> is called, with no arguments.<li><p>When it is <a href=https://dom.spec.whatwg.org/#concept-node-adopt id=custom-element-reactions:concept-node-adopt data-x-internal=concept-node-adopt>adopted</a> into a new document, its <code>adoptedCallback</code> is called, given the old document and new document as
   arguments.<li><p>When any of its attributes are <a href=https://dom.spec.whatwg.org/#concept-element-attributes-change id=custom-element-reactions:concept-element-attributes-change data-x-internal=concept-element-attributes-change>changed</a>, <a href=https://dom.spec.whatwg.org/#concept-element-attributes-append id=custom-element-reactions:concept-element-attributes-append data-x-internal=concept-element-attributes-append>appended</a>, <a href=https://dom.spec.whatwg.org/#concept-element-attributes-remove id=custom-element-reactions:concept-element-attributes-remove data-x-internal=concept-element-attributes-remove>removed</a>, or <a href=https://dom.spec.whatwg.org/#concept-element-attributes-replace id=custom-element-reactions:concept-element-attributes-replace data-x-internal=concept-element-attributes-replace>replaced</a>, its <code>attributeChangedCallback</code> is called, given the attribute's local name, old value,
   new value, and namespace as arguments. (An attribute's old or new value is considered to be null
   when the attribute is added or removed, respectively.)<li><p>When the user agent <a href=form-control-infrastructure.html#reset-the-form-owner id=custom-element-reactions:reset-the-form-owner>resets the form owner</a> of a
   <a href=#form-associated-custom-element id=custom-element-reactions:form-associated-custom-element>form-associated custom element</a> and doing so changes the form owner, its <code>formAssociatedCallback</code> is called, given the new form owner (or null if no owner)
   as an argument.<li><p>When the form owner of a <a href=#form-associated-custom-element id=custom-element-reactions:form-associated-custom-element-2>form-associated custom element</a> is <a href=form-control-infrastructure.html#concept-form-reset id=custom-element-reactions:concept-form-reset>reset</a>, its <code>formResetCallback</code> is
   called.<li><p>When the <a href=form-control-infrastructure.html#concept-fe-disabled id=custom-element-reactions:concept-fe-disabled>disabled</a> state of a
   <a href=#form-associated-custom-element id=custom-element-reactions:form-associated-custom-element-3>form-associated custom element</a> is changed, its <code>formDisabledCallback</code> is called, given the new state as an
   argument.<li><p>When the user agent updates a <a href=#form-associated-custom-element id=custom-element-reactions:form-associated-custom-element-4>form-associated custom element</a>'s value on behalf of
   a user or <a href=browsing-the-web.html#restore-persisted-state id=custom-element-reactions:restore-persisted-state>as part of navigation</a>, its <code>formStateRestoreCallback</code> is called, given the new state and a string indicating
   a reason, "<code>autocomplete</code>" or "<code>restore</code>", as
   arguments.</ul>

  <p>We call these reactions collectively <dfn id=concept-custom-element-reaction>custom
  element reactions</dfn>.</p>

  <p>The way in which <a href=#concept-custom-element-reaction id=custom-element-reactions:concept-custom-element-reaction>custom element reactions</a>
  are invoked is done with special care, to avoid running author code during the middle of delicate
  operations. Effectively, they are delayed until "just before returning to user script". This means
  that for most purposes they appear to execute synchronously, but in the case of complicated
  composite operations (like <a href=https://dom.spec.whatwg.org/#concept-node-clone id=custom-element-reactions:concept-node-clone data-x-internal=concept-node-clone>cloning</a>, or <a href=https://dom.spec.whatwg.org/#concept-range id=custom-element-reactions:concept-range data-x-internal=concept-range>range</a> manipulation), they will instead be delayed until after all
  the relevant user agent processing steps have completed, and then run together as a batch.</p>

  <p>Additionally, the precise ordering of these reactions is managed via a
  somewhat-complicated stack-of-queues system, described below. The intention behind this system is
  to guarantee that <a href=#concept-custom-element-reaction id=custom-element-reactions:concept-custom-element-reaction-2>custom element reactions</a> always are invoked in the
  same order as their triggering actions, at least within the local context of a single <a href=#custom-element id=custom-element-reactions:custom-element-2>custom
  element</a>. (Because <a href=#concept-custom-element-reaction id=custom-element-reactions:concept-custom-element-reaction-3>custom element
  reaction</a> code can perform its own mutations, it is not possible to give a global ordering
  guarantee across multiple elements.)</p>

  

  <hr>

  <p>Each <a id=custom-element-reactions:similar-origin-window-agent href=webappapis.html#similar-origin-window-agent>similar-origin window agent</a> has a <dfn id=custom-element-reactions-stack>custom element reactions stack</dfn>,
  which is initially empty. A <a id=custom-element-reactions:similar-origin-window-agent-2 href=webappapis.html#similar-origin-window-agent>similar-origin window agent</a>'s <dfn id=current-element-queue>current element
  queue</dfn> is the <a href=#element-queue id=custom-element-reactions:element-queue>element queue</a> at the top of its <a href=#custom-element-reactions-stack id=custom-element-reactions:custom-element-reactions-stack>custom element reactions
  stack</a>. Each item in the stack is an <dfn id=element-queue>element queue</dfn>, which is initially empty as
  well. Each item in an <a href=#element-queue id=custom-element-reactions:element-queue-2>element queue</a> is an element. (The elements are not necessarily
  <a href=https://dom.spec.whatwg.org/#concept-element-custom id=custom-element-reactions:concept-element-custom data-x-internal=concept-element-custom>custom</a> yet, since this queue is used for <a href=#upgrades id=custom-element-reactions:upgrades-2>upgrades</a> as well.)</p>

  <p>Each <a href=#custom-element-reactions-stack id=custom-element-reactions:custom-element-reactions-stack-2>custom element reactions stack</a> has an associated <dfn id=backup-element-queue>backup element
  queue</dfn>, which is an initially-empty <a href=#element-queue id=custom-element-reactions:element-queue-3>element queue</a>. Elements are pushed onto the
  <a href=#backup-element-queue id=custom-element-reactions:backup-element-queue>backup element queue</a> during operations that affect the DOM without going through an
  API decorated with <code id=custom-element-reactions:cereactions><a href=#cereactions>[CEReactions]</a></code>, or through the parser's
  <a id=custom-element-reactions:create-an-element-for-the-token href=parsing.html#create-an-element-for-the-token>create an element for the token</a> algorithm. An example of this is a user-initiated
  editing operation which modifies the descendants or attributes of an <a id=custom-element-reactions:editable href=https://w3c.github.io/editing/docs/execCommand/#editable data-x-internal=editable>editable</a>
  element. To prevent reentrancy when processing the <a href=#backup-element-queue id=custom-element-reactions:backup-element-queue-2>backup element queue</a>, each
  <a href=#custom-element-reactions-stack id=custom-element-reactions:custom-element-reactions-stack-3>custom element reactions stack</a> also has a <dfn id=processing-the-backup-element-queue>processing the backup element
  queue</dfn> flag, initially unset.</p>

  <p>All elements have an associated <dfn id=custom-element-reaction-queue>custom element reaction queue</dfn>, initially empty. Each
  item in the <a href=#custom-element-reaction-queue id=custom-element-reactions:custom-element-reaction-queue>custom element reaction queue</a> is of one of two types:</p>

  <ul><li><p>An <dfn id=upgrade-reaction>upgrade reaction</dfn>, which will <a href=#upgrades id=custom-element-reactions:upgrades-3>upgrade</a> the custom element and contains a <a href=#custom-element-definition id=custom-element-reactions:custom-element-definition>custom
   element definition</a>; or<li><p>A <dfn id=callback-reaction>callback reaction</dfn>, which will call a lifecycle callback, and contains a
   callback function as well as a list of arguments.</ul>

  <p>This is all summarized in the following schematic diagram:</p>

  <p><img class=darkmode-aware src=../images/custom-element-reactions.svg alt="A custom element reactions stack consists of a stack of element queues. Zooming in on a particular queue, we see that it contains a number of elements (in our example, <x-a>, then <x-b>, then <x-c>). Any particular element in the queue then has a custom element reaction queue. Zooming in on the custom element reaction queue, we see that it contains a variety of queued-up reactions (in our example, upgrade, then attribute changed, then another attribute changed, then connected)." style="width: 80%; max-width: 580px;"></p>

  <p>To <dfn id=enqueue-an-element-on-the-appropriate-element-queue>enqueue an element on the appropriate element queue</dfn>, given an element
  <var>element</var>, run the following steps:</p>

  <ol><li><p>Let <var>reactionsStack</var> be <var>element</var>'s <a id=custom-element-reactions:relevant-agent href=webappapis.html#relevant-agent>relevant agent</a>'s
   <a href=#custom-element-reactions-stack id=custom-element-reactions:custom-element-reactions-stack-4>custom element reactions stack</a>.<li>
    <p>If <var>reactionsStack</var> is empty, then:</p>

    <ol><li><p>Add <var>element</var> to <var>reactionsStack</var>'s <a href=#backup-element-queue id=custom-element-reactions:backup-element-queue-3>backup element
     queue</a>.<li><p>If <var>reactionsStack</var>'s <a href=#processing-the-backup-element-queue id=custom-element-reactions:processing-the-backup-element-queue>processing the backup element queue</a> flag is
     set, then return.<li><p>Set <var>reactionsStack</var>'s <a href=#processing-the-backup-element-queue id=custom-element-reactions:processing-the-backup-element-queue-2>processing the backup element queue</a>
     flag.<li>
      <p><a id=custom-element-reactions:queue-a-microtask href=webappapis.html#queue-a-microtask>Queue a microtask</a> to perform the following steps:</p>

      <ol><li><p><a href=#invoke-custom-element-reactions id=custom-element-reactions:invoke-custom-element-reactions>Invoke custom element reactions</a> in <var>reactionsStack</var>'s
       <a href=#backup-element-queue id=custom-element-reactions:backup-element-queue-4>backup element queue</a>.<li><p>Unset <var>reactionsStack</var>'s <a href=#processing-the-backup-element-queue id=custom-element-reactions:processing-the-backup-element-queue-3>processing the backup element queue</a>
       flag.</ol>
     </ol>
   <li><p>Otherwise, add <var>element</var> to <var>element</var>'s <a id=custom-element-reactions:relevant-agent-2 href=webappapis.html#relevant-agent>relevant agent</a>'s
   <a href=#current-element-queue id=custom-element-reactions:current-element-queue>current element queue</a>.</ol>

  <p>To <dfn id=enqueue-a-custom-element-callback-reaction data-export="">enqueue a custom element callback reaction</dfn>, given a <a href=#custom-element id=custom-element-reactions:custom-element-3>custom
  element</a> <var>element</var>, a callback name <var>callbackName</var>, and a list of
  arguments <var>args</var>, run the following steps:</p>

  <ol><li><p>Let <var>definition</var> be <var>element</var>'s <a href=https://dom.spec.whatwg.org/#concept-element-custom-element-definition id=custom-element-reactions:concept-element-custom-element-definition data-x-internal=concept-element-custom-element-definition>custom element definition</a>.</p>

   <li><p>Let <var>callback</var> be the value of the entry in <var>definition</var>'s <a href=#concept-custom-element-definition-lifecycle-callbacks id=custom-element-reactions:concept-custom-element-definition-lifecycle-callbacks>lifecycle callbacks</a> with
   key <var>callbackName</var>.<li>
    <p>If <var>callbackName</var> is "<code>connectedMoveCallback</code>" and
    <var>callback</var> is null:

    <ol><li><p>Let <var>disconnectedCallback</var> be the value of the entry in <var>definition</var>'s
     <a href=#concept-custom-element-definition-lifecycle-callbacks id=custom-element-reactions:concept-custom-element-definition-lifecycle-callbacks-2>lifecycle callbacks</a>
     with key "<code>disconnectedCallback</code>".<li><p>Let <var>connectedCallback</var> be the value of the entry in <var>definition</var>'s
     <a href=#concept-custom-element-definition-lifecycle-callbacks id=custom-element-reactions:concept-custom-element-definition-lifecycle-callbacks-3>lifecycle callbacks</a>
     with key "<code>connectedCallback</code>".<li><p>If <var>connectedCallback</var> and <var>disconnectedCallback</var> are null, then
     return.<li>
      <p>Set <var>callback</var> to the following steps:</p>

      <ol><li><p>If <var>disconnectedCallback</var> is not null, then call
       <var>disconnectedCallback</var> with no arguments.<li><p>If <var>connectedCallback</var> is not null, then call <var>connectedCallback</var>
       with no arguments.</ol>
     </ol>
   <li><p>If <var>callback</var> is null, then return.<li>
    <p>If <var>callbackName</var> is "<code>attributeChangedCallback</code>":</p>

    <ol><li><p>Let <var>attributeName</var> be the first element of <var>args</var>.<li><p>If <var>definition</var>'s <a href=#concept-custom-element-definition-observed-attributes id=custom-element-reactions:concept-custom-element-definition-observed-attributes>observed attributes</a> does
     not contain <var>attributeName</var>, then return.</ol>
   <li><p>Add a new <a href=#callback-reaction id=custom-element-reactions:callback-reaction>callback reaction</a> to <var>element</var>'s <a href=#custom-element-reaction-queue id=custom-element-reactions:custom-element-reaction-queue-2>custom element
   reaction queue</a>, with callback function <var>callback</var> and arguments
   <var>args</var>.<li><p><a href=#enqueue-an-element-on-the-appropriate-element-queue id=custom-element-reactions:enqueue-an-element-on-the-appropriate-element-queue>Enqueue an element on the appropriate element queue</a> given
   <var>element</var>.</ol>

  <p>To <dfn id=enqueue-a-custom-element-upgrade-reaction data-export="">enqueue a custom element upgrade reaction</dfn>, given an element
  <var>element</var> and <a href=#custom-element-definition id=custom-element-reactions:custom-element-definition-2>custom element definition</a> <var>definition</var>, run the
  following steps:</p>

  <ol><li><p>Add a new <a href=#upgrade-reaction id=custom-element-reactions:upgrade-reaction>upgrade reaction</a> to <var>element</var>'s <a href=#custom-element-reaction-queue id=custom-element-reactions:custom-element-reaction-queue-3>custom element
   reaction queue</a>, with <a href=#custom-element-definition id=custom-element-reactions:custom-element-definition-3>custom element definition</a>
   <var>definition</var>.<li><p><a href=#enqueue-an-element-on-the-appropriate-element-queue id=custom-element-reactions:enqueue-an-element-on-the-appropriate-element-queue-2>Enqueue an element on the appropriate element queue</a> given
   <var>element</var>.</ol>

  <p>To <dfn id=invoke-custom-element-reactions>invoke custom element reactions</dfn> in an <a href=#element-queue id=custom-element-reactions:element-queue-4>element queue</a>
  <var>queue</var>, run the following steps:</p>

  <ol><li>
    <p>While <var>queue</var> is not <a href=https://infra.spec.whatwg.org/#list-is-empty id=custom-element-reactions:list-is-empty data-x-internal=list-is-empty>empty</a>:</p>

    <ol><li><p>Let <var>element</var> be the result of <a href=https://infra.spec.whatwg.org/#queue-dequeue id=custom-element-reactions:dequeue data-x-internal=dequeue>dequeuing</a>
     from <var>queue</var>.<li><p>Let <var>reactions</var> be <var>element</var>'s <a href=#custom-element-reaction-queue id=custom-element-reactions:custom-element-reaction-queue-4>custom element reaction
     queue</a>.<li>
      <p>Repeat until <var>reactions</var> is empty:</p>

      <ol><li>
        <p>Remove the first element of <var>reactions</var>, and let <var>reaction</var> be that
        element. Switch on <var>reaction</var>'s type:</p>

        <dl class=switch><dt><a href=#upgrade-reaction id=custom-element-reactions:upgrade-reaction-2>upgrade reaction</a><dd>
          <p><a href=#concept-upgrade-an-element id=custom-element-reactions:concept-upgrade-an-element>Upgrade</a> <var>element</var> using
          <var>reaction</var>'s <a href=#custom-element-definition id=custom-element-reactions:custom-element-definition-4>custom element definition</a>.</p>

          <p>If this throws an exception, catch it, and <a href=webappapis.html#report-an-exception id=custom-element-reactions:report-an-exception>report</a> it for <var>reaction</var>'s <a href=#custom-element-definition id=custom-element-reactions:custom-element-definition-5>custom element
          definition</a>'s <a href=#concept-custom-element-definition-constructor id=custom-element-reactions:concept-custom-element-definition-constructor>constructor</a>'s corresponding
          JavaScript object's <a id=custom-element-reactions:associated-realm href=https://webidl.spec.whatwg.org/#dfn-associated-realm data-x-internal=associated-realm>associated realm</a>'s <a href=webappapis.html#concept-realm-global id=custom-element-reactions:concept-realm-global>global object</a>.</p>
         <dt><a href=#callback-reaction id=custom-element-reactions:callback-reaction-2>callback reaction</a><dd>
          <p><a href=https://webidl.spec.whatwg.org/#invoke-a-callback-function id=custom-element-reactions:es-invoking-callback-functions data-x-internal=es-invoking-callback-functions>Invoke</a> <var>reaction</var>'s
          callback function with <var>reaction</var>'s arguments and "<code>report</code>", and <i id=custom-element-reactions:dfn-callback-this-value><a data-x-internal=dfn-callback-this-value href=https://webidl.spec.whatwg.org/#dfn-callback-this-value>callback this value</a></i>
          set to <var>element</var>.</p>
         </dl>
       </ol>
     </ol>
   </ol>

  <hr>

  <p>To ensure <a href=#concept-custom-element-reaction id=custom-element-reactions:concept-custom-element-reaction-4>custom element reactions</a> are
  triggered appropriately, we introduce the <dfn id=cereactions data-dfn-type=extended-attribute data-lt=CEReactions><code>[CEReactions]</code></dfn> IDL <a id=custom-element-reactions:extended-attribute href=https://webidl.spec.whatwg.org/#dfn-extended-attribute data-x-internal=extended-attribute>extended attribute</a>. It
  indicates that the relevant algorithm is to be supplemented with additional steps in order to
  appropriately track and invoke <a href=#concept-custom-element-reaction id=custom-element-reactions:concept-custom-element-reaction-5>custom element
  reactions</a>.</p>

  <p>The <code id=custom-element-reactions:cereactions-2><a href=#cereactions>[CEReactions]</a></code> extended attribute must take no
  arguments, and must not appear on anything other than an operation, attribute, setter, or deleter.
  Additionally, it must not appear on readonly attributes.</p>

  <p>Operations, attributes, setters, or deleters annotated with the <code id=custom-element-reactions:cereactions-3><a href=#cereactions>[CEReactions]</a></code> extended attribute must run the following steps in place
  of the ones specified in their description:</p>

  <ol><li><p><a href=https://infra.spec.whatwg.org/#stack-push id=custom-element-reactions:stack-push data-x-internal=stack-push>Push</a> a new <a href=#element-queue id=custom-element-reactions:element-queue-5>element queue</a> onto this object's
   <a id=custom-element-reactions:relevant-agent-3 href=webappapis.html#relevant-agent>relevant agent</a>'s <a href=#custom-element-reactions-stack id=custom-element-reactions:custom-element-reactions-stack-5>custom element reactions stack</a>.<li><p>Run the originally-specified steps for this construct, catching any exceptions. If the
   steps return a value, let <var>value</var> be the returned value. If they throw an exception, let
   <var>exception</var> be the thrown exception.<li><p>Let <var>queue</var> be the result of <a href=https://infra.spec.whatwg.org/#stack-pop id=custom-element-reactions:stack-pop data-x-internal=stack-pop>popping</a> from this
   object's <a id=custom-element-reactions:relevant-agent-4 href=webappapis.html#relevant-agent>relevant agent</a>'s <a href=#custom-element-reactions-stack id=custom-element-reactions:custom-element-reactions-stack-6>custom element reactions stack</a>.<li><p><a href=#invoke-custom-element-reactions id=custom-element-reactions:invoke-custom-element-reactions-2>Invoke custom element reactions</a> in <var>queue</var>.<li><p>If an exception <var>exception</var> was thrown by the original steps, rethrow
   <var>exception</var>.<li><p>If a value <var>value</var> was returned from the original steps, return
   <var>value</var>.</ol>

  <div class=note>
   <p>The intent behind this extended attribute is somewhat subtle. One way of accomplishing its
   goals would be to say that every operation, attribute, setter, and deleter on the platform
   must have these steps inserted, and to allow implementers to optimize away
   unnecessary cases (where no DOM mutation is possible that could cause <a href=#concept-custom-element-reaction id=custom-element-reactions:concept-custom-element-reaction-6>custom element reactions</a> to occur).</p>

   <p>However, in practice this imprecision could lead to non-interoperable implementations of <a href=#concept-custom-element-reaction id=custom-element-reactions:concept-custom-element-reaction-7>custom element reactions</a>, as some implementations
   might forget to invoke these steps in some cases. Instead, we settled on the approach of
   explicitly annotating all relevant IDL constructs, as a way of ensuring interoperable behavior
   and helping implementations easily pinpoint all cases where these steps are necessary.</p>
  </div>

  <p>Any nonstandard APIs introduced by the user agent that could modify the DOM in such a way as to
  cause <a href=#enqueue-a-custom-element-callback-reaction id=custom-element-reactions:enqueue-a-custom-element-callback-reaction>enqueuing a custom element
  callback reaction</a> or <a href=#enqueue-a-custom-element-upgrade-reaction id=custom-element-reactions:enqueue-a-custom-element-upgrade-reaction>enqueuing a
  custom element upgrade reaction</a>, for example by modifying any attributes or child elements,
  must also be decorated with the <code id=custom-element-reactions:cereactions-4><a href=#cereactions>[CEReactions]</a></code> attribute.</p>

  <div class=note>
   <p>As of the time of this writing, the following nonstandard or not-yet-standardized APIs are
   known to fall into this category:</p>

   <ul><li><p><code id=custom-element-reactions:htmlinputelement><a href=input.html#htmlinputelement>HTMLInputElement</a></code>'s <code>webkitdirectory</code> and <code>incremental</code> IDL attributes<li><p><code id=custom-element-reactions:htmllinkelement><a href=semantics.html#htmllinkelement>HTMLLinkElement</a></code>'s <code>scope</code> IDL attribute</ul>
  </div>

  

  <h4 id=element-internals><span class=secno>4.13.7</span> Element internals<a href=#element-internals class=self-link></a></h4>

  <p>Certain capabilities are meant to be available to a custom element author, but not to a custom
  element consumer. These are provided by the <code id=element-internals:dom-attachinternals><a href=#dom-attachinternals>element.attachInternals()</a></code> method, which returns an instance of
  <code id=element-internals:elementinternals><a href=#elementinternals>ElementInternals</a></code>. The properties and methods of <code id=element-internals:elementinternals-2><a href=#elementinternals>ElementInternals</a></code> allow
  control over internal features which the user agent provides to all elements.</p>

  <dl class=domintro><dt><code><var>element</var>.<a href=#dom-attachinternals id=dom-attachinternals-dev>attachInternals()</a></code><dd><p>Returns an <code id=element-internals:elementinternals-3><a href=#elementinternals>ElementInternals</a></code> object targeting the <a href=#custom-element id=element-internals:custom-element>custom element</a>
   <var>element</var>. Throws an exception if <var>element</var> is not a <a href=#custom-element id=element-internals:custom-element-2>custom
   element</a>, if the "<code>internals</code>" feature was disabled as part of the
   element definition, or if it is called twice on the same element.</dl>

  

  <p>Each <code id=element-internals:htmlelement><a href=dom.html#htmlelement>HTMLElement</a></code> has an <dfn id=attached-internals>attached internals</dfn> (null or an
  <code id=element-internals:elementinternals-4><a href=#elementinternals>ElementInternals</a></code> object), initially null.</p>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals title="The HTMLElement.attachInternals() method returns an ElementInternals object. This method allows a custom element to participate in HTML forms. The ElementInternals interface provides utilities for working with these elements in the same way you would work with any standard HTML form element, and also exposes the Accessibility Object Model to the element.">HTMLElement/attachInternals</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>93+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <dfn data-dfn-for=HTMLElement id=dom-attachinternals data-dfn-type=method><code>attachInternals()</code></dfn> method steps are:</p>

  <ol><li><p>If <a id=element-internals:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=https://dom.spec.whatwg.org/#concept-element-is-value id=element-internals:concept-element-is-value data-x-internal=concept-element-is-value><code>is</code>
   value</a> is not null, then throw a <a id=element-internals:notsupportederror href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a>
   <code id=element-internals:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Let <var>definition</var> be the result of <a href=#look-up-a-custom-element-definition id=element-internals:look-up-a-custom-element-definition>looking up a custom element definition</a> given <a id=element-internals:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=https://dom.spec.whatwg.org/#element-custom-element-registry id=element-internals:element-custom-element-registry data-x-internal=element-custom-element-registry>custom element registry</a>, <a id=element-internals:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s
   <a href=https://dom.spec.whatwg.org/#concept-element-namespace id=element-internals:concept-element-namespace data-x-internal=concept-element-namespace>namespace</a>, <a id=element-internals:this-4 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=https://dom.spec.whatwg.org/#concept-element-local-name id=element-internals:concept-element-local-name data-x-internal=concept-element-local-name>local name</a>, and null.<li><p>If <var>definition</var> is null, then throw a
   <a id=element-internals:notsupportederror-2 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=element-internals:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <var>definition</var>'s <a href=#concept-custom-element-definition-disable-internals id=element-internals:concept-custom-element-definition-disable-internals>disable internals</a> is true,
   then throw a <a id=element-internals:notsupportederror-3 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=element-internals:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <a id=element-internals:this-5 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#attached-internals id=element-internals:attached-internals>attached internals</a> is non-null, then throw a
   <a id=element-internals:notsupportederror-4 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=element-internals:domexception-4><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <a id=element-internals:this-6 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a id=element-internals:custom-element-state href=https://dom.spec.whatwg.org/#concept-element-custom-element-state data-x-internal=custom-element-state>custom element state</a> is not "<code>precustomized</code>" or "<code>custom</code>", then throw a
   <a id=element-internals:notsupportederror-5 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=element-internals:domexception-5><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Set <a id=element-internals:this-7 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#attached-internals id=element-internals:attached-internals-2>attached internals</a> to a new
   <code id=element-internals:elementinternals-5><a href=#elementinternals>ElementInternals</a></code> instance whose <a href=#internals-target id=element-internals:internals-target>target
   element</a> is <a id=element-internals:this-8 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>.<li><p>Return <a id=element-internals:this-9 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#attached-internals id=element-internals:attached-internals-3>attached internals</a>.</ol>

  <h5 id=the-elementinternals-interface><span class=secno>4.13.7.1</span> The <code id=the-elementinternals-interface:elementinternals><a href=#elementinternals>ElementInternals</a></code> interface<a href=#the-elementinternals-interface class=self-link></a></h5><div class="mdn-anno wrapped"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals title="The ElementInternals interface of the Document Object Model gives web developers a way to allow custom elements to fully participate in HTML forms. It provides utilities for working with these elements in the same way you would work with any standard HTML form element, and also exposes the Accessibility Object Model to the element.">ElementInternals</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>93+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div>

  <p>The IDL for the <code id=the-elementinternals-interface:elementinternals-2><a href=#elementinternals>ElementInternals</a></code> interface is as follows, with the various operations and attributes
  defined in the following sections:</p>

  <pre><code class='idl'>[<c- g>Exposed</c->=<c- n>Window</c->]
<c- b>interface</c-> <dfn id='elementinternals' data-dfn-type='interface'><c- g>ElementInternals</c-></dfn> {
  // <a href='#shadow-root-access'>Shadow root access</a>
  <c- b>readonly</c-> <c- b>attribute</c-> <code id='the-elementinternals-interface:shadowroot'><a data-x-internal='shadowroot' href='https://dom.spec.whatwg.org/#interface-shadowroot'><c- n>ShadowRoot</c-></a></code>? <a href='#dom-elementinternals-shadowroot' id='the-elementinternals-interface:dom-elementinternals-shadowroot'><c- g>shadowRoot</c-></a>;

  // <a href='#form-associated-custom-elements'>Form-associated custom elements</a>
  <c- b>undefined</c-> <a href='#dom-elementinternals-setformvalue' id='the-elementinternals-interface:dom-elementinternals-setformvalue'><c- g>setFormValue</c-></a>((<a id='the-elementinternals-interface:file' href='https://w3c.github.io/FileAPI/#dfn-file' data-x-internal='file'><c- n>File</c-></a> <c- b>or</c-> <a href='https://webidl.spec.whatwg.org/#idl-USVString' id='the-elementinternals-interface:idl-usvstring' data-x-internal='idl-usvstring'><c- b>USVString</c-></a> <c- b>or</c-> <a id='the-elementinternals-interface:formdata' href='https://xhr.spec.whatwg.org/#formdata' data-x-internal='formdata'><c- n>FormData</c-></a>)? <c- g>value</c->,
                         <c- b>optional</c-> (<a id='the-elementinternals-interface:file-2' href='https://w3c.github.io/FileAPI/#dfn-file' data-x-internal='file'><c- n>File</c-></a> <c- b>or</c-> <a href='https://webidl.spec.whatwg.org/#idl-USVString' id='the-elementinternals-interface:idl-usvstring-2' data-x-internal='idl-usvstring'><c- b>USVString</c-></a> <c- b>or</c-> <a id='the-elementinternals-interface:formdata-2' href='https://xhr.spec.whatwg.org/#formdata' data-x-internal='formdata'><c- n>FormData</c-></a>)? <c- g>state</c->);

  <c- b>readonly</c-> <c- b>attribute</c-> <a id='the-elementinternals-interface:htmlformelement' href='forms.html#htmlformelement'><c- n>HTMLFormElement</c-></a>? <a href='form-control-infrastructure.html#dom-elementinternals-form' id='the-elementinternals-interface:dom-elementinternals-form'><c- g>form</c-></a>;

  <c- b>undefined</c-> <a href='#dom-elementinternals-setvalidity' id='the-elementinternals-interface:dom-elementinternals-setvalidity'><c- g>setValidity</c-></a>(<c- b>optional</c-> <a href='#validitystateflags' id='the-elementinternals-interface:validitystateflags'><c- n>ValidityStateFlags</c-></a> <c- g>flags</c-> = {},
                        <c- b>optional</c-> <c- b>DOMString</c-> <c- g>message</c->,
                        <c- b>optional</c-> <a id='the-elementinternals-interface:htmlelement' href='dom.html#htmlelement'><c- n>HTMLElement</c-></a> <c- g>anchor</c->);
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>boolean</c-> <a href='form-control-infrastructure.html#dom-elementinternals-willvalidate' id='the-elementinternals-interface:dom-elementinternals-willvalidate'><c- g>willValidate</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <a id='the-elementinternals-interface:validitystate' href='form-control-infrastructure.html#validitystate'><c- n>ValidityState</c-></a> <a href='form-control-infrastructure.html#dom-elementinternals-validity' id='the-elementinternals-interface:dom-elementinternals-validity'><c- g>validity</c-></a>;
  <c- b>readonly</c-> <c- b>attribute</c-> <c- b>DOMString</c-> <a href='#dom-elementinternals-validationmessage' id='the-elementinternals-interface:dom-elementinternals-validationmessage'><c- g>validationMessage</c-></a>;
  <c- b>boolean</c-> <a href='form-control-infrastructure.html#dom-elementinternals-checkvalidity' id='the-elementinternals-interface:dom-elementinternals-checkvalidity'><c- g>checkValidity</c-></a>();
  <c- b>boolean</c-> <a href='form-control-infrastructure.html#dom-elementinternals-reportvalidity' id='the-elementinternals-interface:dom-elementinternals-reportvalidity'><c- g>reportValidity</c-></a>();

  <c- b>readonly</c-> <c- b>attribute</c-> <a id='the-elementinternals-interface:nodelist' href='https://dom.spec.whatwg.org/#interface-nodelist' data-x-internal='nodelist'><c- n>NodeList</c-></a> <a href='forms.html#dom-elementinternals-labels' id='the-elementinternals-interface:dom-elementinternals-labels'><c- g>labels</c-></a>;

  // <a href='#custom-state-pseudo-class'>Custom state pseudo-class</a>
  [<c- g>SameObject</c->] <c- b>readonly</c-> <c- b>attribute</c-> <a href='#customstateset' id='the-elementinternals-interface:customstateset'><c- n>CustomStateSet</c-></a> <a href='#dom-elementinternals-states' id='the-elementinternals-interface:dom-elementinternals-states'><c- g>states</c-></a>;
};

// <a href='#accessibility-semantics'>Accessibility semantics</a>
<a href='#elementinternals' id='the-elementinternals-interface:elementinternals-3'><c- n>ElementInternals</c-></a> <c- b>includes</c-> <a id='the-elementinternals-interface:ariamixin' href='https://w3c.github.io/aria/#ARIAMixin' data-x-internal='ariamixin'><c- n>ARIAMixin</c-></a>;

<c- b>dictionary</c-> <dfn id='validitystateflags' data-dfn-type='dictionary'><c- g>ValidityStateFlags</c-></dfn> {
  <c- b>boolean</c-> <c- g>valueMissing</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>typeMismatch</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>patternMismatch</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>tooLong</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>tooShort</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>rangeUnderflow</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>rangeOverflow</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>stepMismatch</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>badInput</c-> = <c- b>false</c->;
  <c- b>boolean</c-> <c- g>customError</c-> = <c- b>false</c->;
};</code></pre>

  <p>Each <code id=the-elementinternals-interface:elementinternals-4><a href=#elementinternals>ElementInternals</a></code> has a <dfn id=internals-target>target element</dfn>,
  which is a <a href=#custom-element id=the-elementinternals-interface:custom-element>custom element</a>.</p>

  

  <h5 id=shadow-root-access><span class=secno>4.13.7.2</span> Shadow root access<a href=#shadow-root-access class=self-link></a></h5>

  <dl class=domintro><dt><code><var>internals</var>.<a href=#dom-elementinternals-shadowroot id=shadow-root-access:dom-elementinternals-shadowroot>shadowRoot</a></code><dd><p>Returns the <code id=shadow-root-access:shadowroot><a data-x-internal=shadowroot href=https://dom.spec.whatwg.org/#interface-shadowroot>ShadowRoot</a></code> for <var>internals</var>'s <a href=#internals-target id=shadow-root-access:internals-target>target element</a>, if the <a href=#internals-target id=shadow-root-access:internals-target-2>target
   element</a> is a <a id=shadow-root-access:shadow-host href=https://dom.spec.whatwg.org/#element-shadow-host data-x-internal=shadow-host>shadow host</a>, or null otherwise.</dl>

  
  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/shadowRoot title="The shadowRoot read-only property of the ElementInternals interface returns the ShadowRoot for this element.">ElementInternals/shadowRoot</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>93+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>88+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>88+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <dfn data-dfn-for=ElementInternals id=dom-elementinternals-shadowroot data-dfn-type=attribute><code>shadowRoot</code></dfn> getter steps are:</p>

  <ol><li><p>Let <var>target</var> be <a id=shadow-root-access:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#internals-target id=shadow-root-access:internals-target-3>target
   element</a>.<li><p>If <var>target</var> is not a <a id=shadow-root-access:shadow-host-2 href=https://dom.spec.whatwg.org/#element-shadow-host data-x-internal=shadow-host>shadow host</a>, then return null.<li><p>Let <var>shadow</var> be <var>target</var>'s <a href=https://dom.spec.whatwg.org/#concept-element-shadow-root id=shadow-root-access:concept-element-shadow-root data-x-internal=concept-element-shadow-root>shadow root</a>.<li><p>If <var>shadow</var>'s <a id=shadow-root-access:available-to-element-internals href=https://dom.spec.whatwg.org/#shadowroot-available-to-element-internals data-x-internal=available-to-element-internals>available to element internals</a> is false, then return
   null.<li><p>Return <var>shadow</var>.</ol>
  

  <h5 id=form-associated-custom-elements><span class=secno>4.13.7.3</span> Form-associated custom elements<a href=#form-associated-custom-elements class=self-link></a></h5>

  <dl class=domintro><dt><code><var>internals</var>.<a href=#dom-elementinternals-setformvalue id=form-associated-custom-elements:dom-elementinternals-setformvalue>setFormValue</a>(<var>value</var>)</code><dd>
    <p>Sets both the <a href=#face-state id=form-associated-custom-elements:face-state>state</a> and <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value>submission value</a> of <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target>target element</a> to <var>value</var>.</p>

    <p>If <var>value</var> is null, the element won't participate in form submission.</p>
   <dt><code><var>internals</var>.<a href=#dom-elementinternals-setformvalue id=form-associated-custom-elements:dom-elementinternals-setformvalue-2>setFormValue</a>(<var>value</var>,
   <var>state</var>)</code><dd>
    <p>Sets the <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-2>submission value</a> of
    <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-2>target element</a> to
    <var>value</var>, and its <a href=#face-state id=form-associated-custom-elements:face-state-2>state</a> to <var>state</var>.</p>

    <p>If <var>value</var> is null, the element won't participate in form submission.</p>
   <dt><code><var>internals</var>.<a href=form-control-infrastructure.html#dom-elementinternals-form id=form-associated-custom-elements:dom-elementinternals-form>form</a></code><dd><p>Returns the <a id=form-associated-custom-elements:form-owner href=form-control-infrastructure.html#form-owner>form owner</a> of <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-3>target element</a>.<dt><code><var>internals</var>.<a href=#dom-elementinternals-setvalidity id=form-associated-custom-elements:dom-elementinternals-setvalidity>setValidity</a>(<var>flags</var>,
   <var>message</var> [, <var>anchor</var> ])</code><dd><p>Marks <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-4>target element</a> as
   suffering from the constraints indicated by the <var>flags</var> argument, and sets the element's
   validation message to <var>message</var>. If <var>anchor</var> is specified, the user agent might
   use it to indicate problems with the constraints of <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-5>target element</a> when the <a id=form-associated-custom-elements:form-owner-2 href=form-control-infrastructure.html#form-owner>form owner</a> is validated
   interactively or <code id=form-associated-custom-elements:dom-elementinternals-reportvalidity><a href=form-control-infrastructure.html#dom-elementinternals-reportvalidity>reportValidity()</a></code> is
   called.<dt><code><var>internals</var>.<a href=#dom-elementinternals-setvalidity id=form-associated-custom-elements:dom-elementinternals-setvalidity-2>setValidity</a>({})</code><dd><p>Marks <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-6>target element</a> as
   <a href=form-control-infrastructure.html#concept-fv-valid id=form-associated-custom-elements:concept-fv-valid>satisfying its constraints</a>.<dt><code><var>internals</var>.<a href=form-control-infrastructure.html#dom-elementinternals-willvalidate id=form-associated-custom-elements:dom-elementinternals-willvalidate>willValidate</a></code><dd><p>Returns true if <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-7>target
   element</a> will be validated when the form is submitted; false otherwise.<dt><code><var>internals</var>.<a href=form-control-infrastructure.html#dom-elementinternals-validity id=form-associated-custom-elements:dom-elementinternals-validity>validity</a></code><dd><p>Returns the <code id=form-associated-custom-elements:validitystate><a href=form-control-infrastructure.html#validitystate>ValidityState</a></code> object for <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-8>target element</a>.<dt><code><var>internals</var>.<a href=#dom-elementinternals-validationmessage id=form-associated-custom-elements:dom-elementinternals-validationmessage>validationMessage</a></code><dd><p>Returns the error message that would be shown to the user if <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-9>target element</a> was to be checked for validity.<dt><code><var>valid</var> = <var>internals</var>.<a href=form-control-infrastructure.html#dom-elementinternals-checkvalidity id=form-associated-custom-elements:dom-elementinternals-checkvalidity>checkValidity()</a></code><dd><p>Returns true if <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-10>target
   element</a> has no validity problems; false otherwise. Fires an <code id=form-associated-custom-elements:event-invalid><a href=indices.html#event-invalid>invalid</a></code> event at the element in the latter case.<dt><code><var>valid</var> = <var>internals</var>.<a href=form-control-infrastructure.html#dom-elementinternals-reportvalidity id=form-associated-custom-elements:dom-elementinternals-reportvalidity-2>reportValidity()</a></code><dd><p>Returns true if <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-11>target
   element</a> has no validity problems; otherwise, returns false, fires an <code id=form-associated-custom-elements:event-invalid-2><a href=indices.html#event-invalid>invalid</a></code> event at the element, and (if the event isn't canceled)
   reports the problem to the user.<dt><code><var>internals</var>.<a href=forms.html#dom-elementinternals-labels id=form-associated-custom-elements:dom-elementinternals-labels>labels</a></code><dd><p>Returns a <code id=form-associated-custom-elements:nodelist><a data-x-internal=nodelist href=https://dom.spec.whatwg.org/#interface-nodelist>NodeList</a></code> of all the <code id=form-associated-custom-elements:the-label-element><a href=forms.html#the-label-element>label</a></code> elements that
   <var>internals</var>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-12>target element</a> is associated
   with.</dl>

  <p>Each <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element>form-associated custom element</a> has <dfn id=face-submission-value>submission value</dfn>. It is used to provide one or more
  <a href=form-control-infrastructure.html#form-entry id=form-associated-custom-elements:form-entry>entries</a> on form submission.
  The initial value of <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-3>submission value</a> is null, and
  <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-4>submission value</a> can be null, a string, a
  <code id=form-associated-custom-elements:file><a data-x-internal=file href=https://w3c.github.io/FileAPI/#dfn-file>File</a></code>, or a <a id=form-associated-custom-elements:list href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=form-control-infrastructure.html#form-entry id=form-associated-custom-elements:form-entry-2>entries</a>.</p>

  <p>Each <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-2>form-associated custom element</a> has <dfn id=face-state>state</dfn>.
  It is information with which the user agent can restore a user's input for the element.
  The initial value of <a href=#face-state id=form-associated-custom-elements:face-state-3>state</a> is null, and <a href=#face-state id=form-associated-custom-elements:face-state-4>state</a> can be null, a string, a <code id=form-associated-custom-elements:file-2><a data-x-internal=file href=https://w3c.github.io/FileAPI/#dfn-file>File</a></code>, or a
  <a id=form-associated-custom-elements:list-2 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=form-control-infrastructure.html#form-entry id=form-associated-custom-elements:form-entry-3>entries</a>.</p>

  <p>The <code id=form-associated-custom-elements:dom-elementinternals-setformvalue-3><a href=#dom-elementinternals-setformvalue>setFormValue()</a></code> method is used by
  the custom element author to set the element's <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-5>submission
  value</a> and <a href=#face-state id=form-associated-custom-elements:face-state-5>state</a>, thus communicating these to the user
  agent.</p>

  <p>When the user agent believes it is a good idea to restore a <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-3>form-associated custom
  element</a>'s <a href=#face-state id=form-associated-custom-elements:face-state-6>state</a>, for example <a href=browsing-the-web.html#restore-persisted-state id=form-associated-custom-elements:restore-persisted-state>after navigation</a> or restarting the user agent, they may <a href=#enqueue-a-custom-element-callback-reaction id=form-associated-custom-elements:enqueue-a-custom-element-callback-reaction>enqueue a
  custom element callback reaction</a> with that element, callback name "<code>formStateRestoreCallback</code>", and « the state to be restored, "<code>restore</code>" ».</p>

  <p>If the user agent has a form-filling assist feature, then when the feature is invoked, it may
  <a href=#enqueue-a-custom-element-callback-reaction id=form-associated-custom-elements:enqueue-a-custom-element-callback-reaction-2>enqueue a custom element callback reaction</a> with a <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-4>form-associated custom
  element</a>, callback name "<code>formStateRestoreCallback</code>", and « the state
  value determined by history of state value and some heuristics, "<code>autocomplete</code>" ».</p>

  <p>In general, the <a href=#face-state id=form-associated-custom-elements:face-state-7>state</a> is information specified by a user, and
  the <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-6>submission value</a> is a value after canonicalization
  or sanitization, suitable for submission to the server. The following examples makes this
  concrete:</p>

  <p class=example>Suppose that we have a <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-5>form-associated custom element</a> which asks a
  user to specify a date. The user specifies <kbd>"3/15/2019"</kbd>, but the control wishes to
  submit <code>"2019-03-15"</code> to the server. <kbd>"3/15/2019"</kbd> would be a <a href=#face-state id=form-associated-custom-elements:face-state-8>state</a> of the element, and <code>"2019-03-15"</code> would be
  a <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-7>submission value</a>.</p>

  <p class=example>Suppose you develop a custom element emulating a the behavior of the existing
  <a href="input.html#checkbox-state-(type=checkbox)" id="form-associated-custom-elements:checkbox-state-(type=checkbox)">checkbox</a> <code id=form-associated-custom-elements:the-input-element><a href=input.html#the-input-element>input</a></code> type. Its <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-8>submission value</a> would be the value of its <code>value</code> content attribute, or the string <code>"on"</code>. Its <a href=#face-state id=form-associated-custom-elements:face-state-9>state</a> would be one of <code>"checked"</code>, <code>"unchecked"</code>, <code>"checked/indeterminate"</code>, or <code>"unchecked/indeterminate"</code>.</p>

  

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setFormValue title="The setFormValue() method of the ElementInternals interface sets the element's submission value and state, communicating these to the user agent.">ElementInternals/setFormValue</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>98+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <dfn data-dfn-for=ElementInternals id=dom-elementinternals-setformvalue data-dfn-type=method><code>setFormValue(<var>value</var>,
  <var>state</var>)</code></dfn> method steps are:</p>

  <ol><li><p>Let <var>element</var> be <a id=form-associated-custom-elements:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-13>target
   element</a>.<li><p>If <var>element</var> is not a <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-6>form-associated custom element</a>, then throw a
   <a id=form-associated-custom-elements:notsupportederror href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=form-associated-custom-elements:domexception><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Set <var>element</var>'s <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-9>submission value</a> to <var>value</var> if <var>value</var> is
   not a <code id=form-associated-custom-elements:formdata><a data-x-internal=formdata href=https://xhr.spec.whatwg.org/#formdata>FormData</a></code> object, or to a <a href=https://infra.spec.whatwg.org/#list-clone id=form-associated-custom-elements:list-clone data-x-internal=list-clone>clone</a> of
   <var>value</var>'s <a href=https://xhr.spec.whatwg.org/#concept-formdata-entry-list id=form-associated-custom-elements:formdata-entry-list data-x-internal=formdata-entry-list>entry list</a> otherwise.<li><p>If the <var>state</var> argument of the function is omitted, set <var>element</var>'s
   <a href=#face-state id=form-associated-custom-elements:face-state-10>state</a> to its <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-10>submission
   value</a>.

   <li><p>Otherwise, if <var>state</var> is a <code id=form-associated-custom-elements:formdata-2><a data-x-internal=formdata href=https://xhr.spec.whatwg.org/#formdata>FormData</a></code> object, set <var>element</var>'s
   <a href=#face-state id=form-associated-custom-elements:face-state-11>state</a> to a <a href=https://infra.spec.whatwg.org/#list-clone id=form-associated-custom-elements:list-clone-2 data-x-internal=list-clone>clone</a> of
   <var>state</var>'s <a href=https://xhr.spec.whatwg.org/#concept-formdata-entry-list id=form-associated-custom-elements:formdata-entry-list-2 data-x-internal=formdata-entry-list>entry list</a>.<li><p>Otherwise, set <var>element</var>'s <a href=#face-state id=form-associated-custom-elements:face-state-12>state</a> to
   <var>state</var>.</ol>

  <hr>

  <p>Each <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-7>form-associated custom element</a> has validity flags named
  <code>valueMissing</code>, <code>typeMismatch</code>,
  <code>patternMismatch</code>, <code>tooLong</code>,
  <code>tooShort</code>, <code>rangeUnderflow</code>,
  <code>rangeOverflow</code>, <code>stepMismatch</code>, and
  <code>customError</code>. They are false initially.</p>

  <p>Each <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-8>form-associated custom element</a> has a
  <dfn id=face-validation-message>validation message</dfn> string. It is the empty string
  initially.</p>

  <p>Each <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-9>form-associated custom element</a> has a
  <dfn id=face-validation-anchor>validation anchor</dfn> element. It is null initially.</p>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/setValidity title="The setValidity() method of the ElementInternals interface sets the validity of the element.">ElementInternals/setValidity</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>98+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <dfn data-dfn-for=ElementInternals id=dom-elementinternals-setvalidity data-dfn-type=method><code>setValidity(<var>flags</var>, <var>message</var>,
  <var>anchor</var>)</code></dfn> method steps are:</p>

  <ol><li><p>Let <var>element</var> be <a id=form-associated-custom-elements:this-2 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-14>target
   element</a>.<li><p>If <var>element</var> is not a <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-10>form-associated custom element</a>, then throw a
   <a id=form-associated-custom-elements:notsupportederror-2 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=form-associated-custom-elements:domexception-2><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>If <var>flags</var> contains one or more true values and <var>message</var> is not given
   or is the empty string, then throw a <code id=form-associated-custom-elements:typeerror><a data-x-internal=typeerror href=https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-typeerror>TypeError</a></code>.<li><p>For each entry <var>flag</var> → <var>value</var> of <var>flags</var>, set
   <var>element</var>'s validity flag with the name <var>flag</var> to <var>value</var>.<li><p>Set <var>element</var>'s <a href=#face-validation-message id=form-associated-custom-elements:face-validation-message>validation message</a>
   to the empty string if <var>message</var> is not given or all of <var>element</var>'s validity
   flags are false, or to <var>message</var> otherwise.<li><p>If <var>element</var>'s <code>customError</code> validity flag is true, then set
   <var>element</var>'s <a id=form-associated-custom-elements:custom-validity-error-message href=form-control-infrastructure.html#custom-validity-error-message>custom validity error message</a> to <var>element</var>'s
   <a href=#face-validation-message id=form-associated-custom-elements:face-validation-message-2>validation message</a>. Otherwise, set
   <var>element</var>'s <a id=form-associated-custom-elements:custom-validity-error-message-2 href=form-control-infrastructure.html#custom-validity-error-message>custom validity error message</a> to the empty string.<li><p>If <var>anchor</var> is not given, then set it to <var>element</var>.<li><p>Otherwise, if <var>anchor</var> is not a <a id=form-associated-custom-elements:shadow-including-inclusive-descendant href=https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-descendant data-x-internal=shadow-including-inclusive-descendant>shadow-including inclusive
   descendant</a> of <var>element</var>, then throw a <a id=form-associated-custom-elements:notfounderror href=https://webidl.spec.whatwg.org/#notfounderror data-x-internal=notfounderror>"<code>NotFoundError</code>"</a>
   <code id=form-associated-custom-elements:domexception-3><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Set <var>element</var>'s <a href=#face-validation-anchor id=form-associated-custom-elements:face-validation-anchor>validation anchor</a> to
   <var>anchor</var>.</ol>

  <div class="mdn-anno wrapped before"><button onclick=toggleStatus(this) class=mdn-anno-btn><b title="Support in all current engines." class=all-engines-flag>✔</b><span>MDN</span></button><div class=feature><p><a href=https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/validationMessage title="The validationMessage read-only property of the ElementInternals interface returns the validation message for the element.">ElementInternals/validationMessage</a><p class=all-engines-text>Support in all current engines.<div class=support><span class="firefox yes"><span>Firefox</span><span>98+</span></span><span class="safari yes"><span>Safari</span><span>16.4+</span></span><span class="chrome yes"><span>Chrome</span><span>77+</span></span><hr><span class="opera unknown"><span>Opera</span><span>?</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span><hr><span class="edge unknown"><span>Edge (Legacy)</span><span>?</span></span><span class="ie no"><span>Internet Explorer</span><span>No</span></span><hr><span class="firefox_android unknown"><span>Firefox Android</span><span>?</span></span><span class="safari_ios unknown"><span>Safari iOS</span><span>?</span></span><span class="chrome_android unknown"><span>Chrome Android</span><span>?</span></span><span class="webview_android unknown"><span>WebView Android</span><span>?</span></span><span class="samsunginternet_android unknown"><span>Samsung Internet</span><span>?</span></span><span class="opera_android unknown"><span>Opera Android</span><span>?</span></span></div></div></div><p>The <dfn data-dfn-for=ElementInternals id=dom-elementinternals-validationmessage data-dfn-type=attribute><code>validationMessage</code></dfn> getter steps
  are:</p>

  <ol><li><p>Let <var>element</var> be <a id=form-associated-custom-elements:this-3 href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#internals-target id=form-associated-custom-elements:internals-target-15>target
   element</a>.<li><p>If <var>element</var> is not a <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-11>form-associated custom element</a>, then throw a
   <a id=form-associated-custom-elements:notsupportederror-3 href=https://webidl.spec.whatwg.org/#notsupportederror data-x-internal=notsupportederror>"<code>NotSupportedError</code>"</a> <code id=form-associated-custom-elements:domexception-4><a data-x-internal=domexception href=https://webidl.spec.whatwg.org/#dfn-DOMException>DOMException</a></code>.<li><p>Return <var>element</var>'s <a href=#face-validation-message id=form-associated-custom-elements:face-validation-message-3>validation
   message</a>.</ol>

  <p>The <dfn id=face-entry-construction>entry construction algorithm</dfn> for a
  <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-12>form-associated custom element</a>, given an element <var>element</var> and an
  <a id=form-associated-custom-elements:entry-list href=form-control-infrastructure.html#entry-list>entry list</a> <var>entry list</var>, consists of the following steps:</p>

  <ol><li>
    <p>If <var>element</var>'s <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-11>submission value</a> is a
    <a id=form-associated-custom-elements:list-3 href=https://infra.spec.whatwg.org/#list data-x-internal=list>list</a> of <a href=form-control-infrastructure.html#form-entry id=form-associated-custom-elements:form-entry-4>entries</a>, then <a href=https://infra.spec.whatwg.org/#list-append id=form-associated-custom-elements:list-append data-x-internal=list-append>append</a> each item of <var>element</var>'s <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-12>submission value</a> to <var>entry list</var>, and return.</p>

    <p class=note>In this case, user agent does not refer to the
    <code id=form-associated-custom-elements:attr-fe-name><a href=form-control-infrastructure.html#attr-fe-name>name</a></code> content attribute value. An implementation of
    <a href=#form-associated-custom-element id=form-associated-custom-elements:form-associated-custom-element-13>form-associated custom element</a> is responsible to decide names of
    <a href=form-control-infrastructure.html#form-entry id=form-associated-custom-elements:form-entry-5>entries</a>. They can be the
    <code id=form-associated-custom-elements:attr-fe-name-2><a href=form-control-infrastructure.html#attr-fe-name>name</a></code> content attribute value, they can be strings based on
    the <code id=form-associated-custom-elements:attr-fe-name-3><a href=form-control-infrastructure.html#attr-fe-name>name</a></code> content attribute value, or they can be unrelated
    to the <code id=form-associated-custom-elements:attr-fe-name-4><a href=form-control-infrastructure.html#attr-fe-name>name</a></code> content attribute.</p>
   <li><p>If the element does not have a <code id=form-associated-custom-elements:attr-fe-name-5><a href=form-control-infrastructure.html#attr-fe-name>name</a></code> attribute
   specified, or its <code id=form-associated-custom-elements:attr-fe-name-6><a href=form-control-infrastructure.html#attr-fe-name>name</a></code> attribute's value is the empty string,
   then return.<li><p>If the element's <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-13>submission value</a> is not
   null, <a id=form-associated-custom-elements:create-an-entry href=form-control-infrastructure.html#create-an-entry>create an entry</a> with the <code id=form-associated-custom-elements:attr-fe-name-7><a href=form-control-infrastructure.html#attr-fe-name>name</a></code> attribute
   value and the <a href=#face-submission-value id=form-associated-custom-elements:face-submission-value-14>submission value</a>, and <a href=https://infra.spec.whatwg.org/#list-append id=form-associated-custom-elements:list-append-2 data-x-internal=list-append>append</a> it to <var>entry list</var>.</ol>

  

  <h5 id=accessibility-semantics><span class=secno>4.13.7.4</span> Accessibility semantics<a href=#accessibility-semantics class=self-link></a></h5>

  <dl class=domintro><dt><code><var>internals</var>.<a href=https://w3c.github.io/aria/#idl-def-ariamixin-role id=accessibility-semantics:dom-ariamixin-role data-x-internal=dom-ariamixin-role>role</a> [ = <var>value</var> ]</code><dd><p>Sets or retrieves the default ARIA role for <var>internals</var>'s <a href=#internals-target id=accessibility-semantics:internals-target>target element</a>, which will be used unless the page author
   overrides it using the <code id=accessibility-semantics:attr-aria-role><a href=infrastructure.html#attr-aria-role>role</a></code> attribute.<dt><code><var>internals</var>.<a href=https://w3c.github.io/aria/#idl-def-ariamixin-ariaactivedescendantelement id=accessibility-semantics:dom-ariamixin-aria* data-x-internal=dom-ariamixin-aria*>aria*</a> [ = <var>value</var> ]</code><dd><p>Sets or retrieves various default ARIA states or property values for
   <var>internals</var>'s <a href=#internals-target id=accessibility-semantics:internals-target-2>target element</a>, which will be used
   unless the page author overrides them using the <code id=accessibility-semantics:attr-aria-*><a href=infrastructure.html#attr-aria-*>aria-*</a></code>
   attributes.</dl>

  

  

  <p>Each <a href=#custom-element id=accessibility-semantics:custom-element>custom element</a> has an <dfn id=internal-content-attribute-map>internal content attribute map</dfn>, which is a
  <a href=https://infra.spec.whatwg.org/#ordered-map id=accessibility-semantics:ordered-map data-x-internal=ordered-map>map</a>, initially empty. See the <a href=dom.html#wai-aria>Requirements
  related to ARIA and to platform accessibility APIs</a> section for information on how this impacts
  platform accessibility APIs.</p>

  

  <h5 id=custom-state-pseudo-class><span class=secno>4.13.7.5</span> Custom state pseudo-class<a href=#custom-state-pseudo-class class=self-link></a></h5>

  <dl class=domintro><dt><code><var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states>states</a>.add(<var>value</var>)</code><dd>
    <p>Adds the string <var>value</var> to the element's <a href=#states-set id=custom-state-pseudo-class:states-set>states set</a> to be exposed as a
    pseudo-class.</p>
   <dt><code><var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-2>states</a>.has(<var>value</var>)</code><dd>
    <p>Returns true if <var>value</var> is in the element's <a href=#states-set id=custom-state-pseudo-class:states-set-2>states set</a>, otherwise
    false.</p>
   <dt><code><var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-3>states</a>.delete(<var>value</var>)</code><dd>
    <p>If the element's <a href=#states-set id=custom-state-pseudo-class:states-set-3>states set</a> has <var>value</var>, then it will be removed and
    true will be returned. Otherwise, false will be returned.</p>
   <dt><code><var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-4>states</a>.clear()</code><dd>
    <p>Removes all values from the element's <a href=#states-set id=custom-state-pseudo-class:states-set-4>states set</a>.</p>
   <dt><code>for (const <var>stateName</var> of <var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-5>states</a>)</code><dt><code>for (const <var>stateName</var> of <var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-6>states</a>.entries())</code><dt><code>for (const <var>stateName</var> of <var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-7>states</a>.keys())</code><dt><code>for (const <var>stateName</var> of <var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-8>states</a>.values())</code><dd>
    <p>Iterates over all values in the element's <a href=#states-set id=custom-state-pseudo-class:states-set-5>states set</a>.</p>
   <dt><code><var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-9>states</a>.forEach(<var>callback</var>)</code><dd>
    <p>Iterates over all values in the element's <a href=#states-set id=custom-state-pseudo-class:states-set-6>states set</a> by calling
    <var>callback</var> once for each value.</p>
   <dt><code><var>internals</var>.<a href=#dom-elementinternals-states id=custom-state-pseudo-class:dom-elementinternals-states-10>states</a>.size</code><dd>
    <p>Returns the number of values in the element's <a href=#states-set id=custom-state-pseudo-class:states-set-7>states set</a>.</p>
   </dl>

  
   <p>Each <a href=#custom-element id=custom-state-pseudo-class:custom-element>custom element</a> has a <dfn id=states-set>states set</dfn>, which is a
   <code id=custom-state-pseudo-class:customstateset><a href=#customstateset>CustomStateSet</a></code>, initially empty.</p>

   <pre><code class='idl'>[<c- g>Exposed</c->=<c- n>Window</c->]
<c- b>interface</c-> <dfn id='customstateset' data-dfn-type='interface'><c- g>CustomStateSet</c-></dfn> {
  <c- b>setlike</c->&lt;<c- b>DOMString</c->&gt;;
};</code></pre>

   <p>The <dfn data-dfn-for=HTMLElement id=dom-elementinternals-states data-dfn-type=attribute><code>states</code></dfn> getter steps are to return
   <a id=custom-state-pseudo-class:this href=https://webidl.spec.whatwg.org/#this data-x-internal=this>this</a>'s <a href=#internals-target id=custom-state-pseudo-class:internals-target>target element</a>'s <a href=#states-set id=custom-state-pseudo-class:states-set-8>states
   set</a>.</p>
  

  <div class=example>
   <p>The <a href=#states-set id=custom-state-pseudo-class:states-set-9>states set</a> can expose boolean states represented by existence/non-existence
   of string values. If an author wants to expose a state which can have three values, it can be
   converted to three exclusive boolean states. For example, a state called <code>readyState</code> with <code>"loading"</code>, <code>"interactive"</code>, and <code>"complete"</code> values can be mapped to
   three exclusive boolean states, <code>"loading"</code>, <code>"interactive"</code>, and <code>"complete"</code>:</p>

   <pre><code class='js'><c- c1>// Change the readyState from anything to &quot;complete&quot;.</c->
<c- k>this</c-><c- p>.</c->_readyState <c- o>=</c-> <c- u>&quot;complete&quot;</c-><c- p>;</c->
<c- k>this</c-><c- p>.</c->_internals<c- p>.</c->states<c- p>.</c-><c- k>delete</c-><c- p>(</c-><c- u>&quot;loading&quot;</c-><c- p>);</c->
<c- k>this</c-><c- p>.</c->_internals<c- p>.</c->states<c- p>.</c-><c- k>delete</c-><c- p>(</c-><c- u>&quot;interactive&quot;</c-><c- p>);</c->
<c- k>this</c-><c- p>.</c->_internals<c- p>.</c->states<c- p>.</c->add<c- p>(</c-><c- u>&quot;complete&quot;</c-><c- p>);</c-></code></pre>
  </div>

  <nav><a href=canvas.html>← 4.12.5 The canvas element</a> — <a href=index.html>Table of Contents</a> — <a href=semantics-other.html>4.14 Common idioms without dedicated elements →</a></nav>
